Commit 249b839498114354466d683e1cb030b93997b896

Authored by xp.Huang
2 parents 2f6bd6e7 9f612429

Merge branch 'dev-ft' into 'main'

预览打包小程序完成

See merge request huang/thingskit-app!22
Showing 52 changed files with 1114 additions and 3452 deletions

Too many changes to show.

To preserve performance only 52 of 68 files are displayed.

@@ -71,16 +71,11 @@ @@ -71,16 +71,11 @@
71 <view v-if="list.status !== 'CLEARED_ACK'" style="width: 500rpx;margin-left: 80rpx;margin-top: 44rpx;"> 71 <view v-if="list.status !== 'CLEARED_ACK'" style="width: 500rpx;margin-left: 80rpx;margin-top: 44rpx;">
72 <u-button @click="handleSubmit" type="primary" shape="circle" text="处理"></u-button> 72 <u-button @click="handleSubmit" type="primary" shape="circle" text="处理"></u-button>
73 </view> 73 </view>
74 - <f-tabbar></f-tabbar>  
75 </view> 74 </view>
76 </template> 75 </template>
77 76
78 <script> 77 <script>
79 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
80 export default { 78 export default {
81 - components: {  
82 - fTabbar  
83 - },  
84 data() { 79 data() {
85 return { 80 return {
86 formModel: { 81 formModel: {
alarmSubPage/alarmDetailPage/static/alarmDetail.scss renamed from pages/alarm/static/alarmDetail.scss
1 import store from '@/store'; 1 import store from '@/store';
2 import base from "@/config/baseUrl"; 2 import base from "@/config/baseUrl";
3 -import QQMapWX from '@/plugins/qqmap-wx-jssdk.js'; 3 +// import QQMapWX from '@/plugins/qqmap-wx-jssdk.js';
4 import { 4 import {
5 getAppLatLon 5 getAppLatLon
6 } from '@/plugins/utils'; 6 } from '@/plugins/utils';
1 import base from "@/config/baseUrl"; 1 import base from "@/config/baseUrl";
2 -import store from '@/store';  
3 -import {  
4 - judgeLogin  
5 -} from '@/config/login'; 2 +import store from "@/store";
  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 = store.state.userInfo.isToken || (uni.getStorageSync('userInfo').isToken || undefined)  
10 - // #ifdef H5  
11 - window.sessionStorage.getItem('userInfo').isToken;  
12 - // #endif  
13 - /* config 为默认全局配置*/  
14 - config.baseURL = base.baseUrl; /* 根域名 */  
15 - config.header = {  
16 - 'Content-Type': 'application/json',  
17 - 'Authorization': 'Bearer ' + token  
18 - }  
19 - config.custom = {  
20 - load: true, //是否显示加载动画  
21 - isFactory: true, //true:返回的数据成功只返回data false:返回response  
22 - catch: true, //默认数据返回不成功进入catch返回  
23 - auth: true, //token  
24 - }  
25 - return config  
26 -}) 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 + config.baseURL = base.baseUrl; /* 根域名 */
  16 + config.header = {
  17 + "Content-Type": "application/json",
  18 + Authorization: "Bearer " + token,
  19 + };
  20 + config.custom = {
  21 + load: true, //是否显示加载动画
  22 + isFactory: true, //true:返回的数据成功只返回data false:返回response
  23 + catch: true, //默认数据返回不成功进入catch返回
  24 + auth: true, //token
  25 + };
  26 + return config;
  27 +});
27 28
28 // 请求拦截 29 // 请求拦截
29 -uni.$u.http.interceptors.request.use((config) => { // 可使用async await 做异步操作  
30 - // 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{}  
31 - config.data = config.data || {}  
32 - // 根据custom参数中配置的是否需要token,添加对应的请求头  
33 - if (config?.custom?.auth) {  
34 - config.header.Authorization = 'Bearer ' + store.state.userInfo.isToken || (uni.getStorageSync(  
35 - 'userInfo').isToken || undefined)  
36 - }  
37 - console.log("请求开始", config);  
38 - if (config?.custom?.load) {  
39 - //打开加载动画  
40 - store.commit("setLoadingShow", true);  
41 - } 30 +uni.$u.http.interceptors.request.use(
  31 + (config) => {
  32 + // 可使用async await 做异步操作
  33 + // 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{}
  34 + config.data = config.data || {};
  35 + // 根据custom参数中配置的是否需要token,添加对应的请求头
  36 + if (config?.custom?.auth) {
  37 + config.header.Authorization =
  38 + "Bearer " + store.state.userInfo.isToken ||
  39 + uni.getStorageSync("userInfo").isToken ||
  40 + undefined;
  41 + }
  42 + console.log("请求开始", config);
  43 + if (config?.custom?.load) {
  44 + //打开加载动画
  45 + store.commit("setLoadingShow", true);
  46 + }
42 47
43 - return config  
44 -}, config => { // 可使用async await 做异步操作  
45 - return Promise.reject(config)  
46 -}) 48 + return config;
  49 + },
  50 + (config) => {
  51 + // 可使用async await 做异步操作
  52 + return Promise.reject(config);
  53 + }
  54 +);
47 55
48 // 响应拦截 56 // 响应拦截
49 -uni.$u.http.interceptors.response.use((response) => {  
50 - /* 对响应成功做点什么 可使用async await 做异步操作*/  
51 - // 关闭加载动画  
52 - store.commit("setLoadingShow", false);  
53 - const data = response.data  
54 - // 自定义参数  
55 - const custom = response.config?.custom  
56 - // code: 200、请求成功 其他,没有更多参数 401、被迫下线重新登录、  
57 - if (response.statusCode == 200) {  
58 - return Promise.resolve(data)  
59 - // if (!custom.isFactory) {  
60 - // return Promise.reject(response.data)  
61 - // } else {  
62 - // return data.data === undefined ? {} : Promise.reject(response.data)  
63 - // }  
64 - } else if (response.statusCode == 401) { //被迫下线重新登录  
65 - // 清空登录信息  
66 - store.commit("emptyUserInfo");  
67 - // 20秒节流,弹窗登录  
68 - uni.$u.throttle(judgeLogin(), 20000)  
69 - return new Promise(() => {})  
70 - } else {  
71 - // 如果没有显式定义custom的toast参数为false的话,默认对报错进行toast弹出提示  
72 - if (custom.toast !== false) {  
73 - uni.$u.toast(data.message || data.msg)  
74 - }  
75 - // 如果需要catch返回,则进行reject  
76 - if (custom?.catch) {  
77 - return Promise.reject(data)  
78 - } else {  
79 - // 否则返回一个pending中的promise,请求不会进入catch中  
80 - return new Promise(() => {})  
81 - }  
82 - }  
83 -}, (response) => {  
84 - // 关闭加载动画  
85 - store.commit("setLoadingShow", false);  
86 - // 对响应错误做点什么 (statusCode !== 200)  
87 - let errorData = '请检查网络或服务器'  
88 - let message = response.data?.message || response?.errMsg  
89 - if (message == "request:fail url not in domain list") {  
90 - errorData = '检查请求域名是否添加了域名白名单'  
91 - } else if (message == 'request:fail timeout') {  
92 - errorData = '请求超时:请检查网络'  
93 - } else if (message == 'Token has expired') {  
94 - errorData = 'Token失效,请重新登录'  
95 - uni.reLaunch({  
96 - url: '/pages/public/login'  
97 - })  
98 - store.commit('emptyUserInfo')  
99 - } else if (message == 'Invalid username or password') {  
100 - errorData = '用户名或者密码无效'  
101 - uni.reLaunch({  
102 - url: '/pages/public/login'  
103 - })  
104 - store.commit('emptyUserInfo')  
105 - } else {  
106 - errorData = message || '请检查网络或服务器'  
107 - }  
108 - uni.$u.toast(errorData)  
109 - return Promise.reject(response)  
110 -}) 57 +uni.$u.http.interceptors.response.use(
  58 + (response) => {
  59 + /* 对响应成功做点什么 可使用async await 做异步操作*/
  60 + // 关闭加载动画
  61 + store.commit("setLoadingShow", false);
  62 + const data = response.data;
  63 + // 自定义参数
  64 + const custom = response.config?.custom;
  65 + // code: 200、请求成功 其他,没有更多参数 401、被迫下线重新登录、
  66 + if (response.statusCode == 200) {
  67 + return Promise.resolve(data);
  68 + // if (!custom.isFactory) {
  69 + // return Promise.reject(response.data)
  70 + // } else {
  71 + // return data.data === undefined ? {} : Promise.reject(response.data)
  72 + // }
  73 + } else if (response.statusCode == 401) {
  74 + //被迫下线重新登录
  75 + // 清空登录信息
  76 + store.commit("emptyUserInfo");
  77 + // 20秒节流,弹窗登录
  78 + uni.$u.throttle(judgeLogin(), 20000);
  79 + return new Promise(() => {});
  80 + } else {
  81 + // 如果没有显式定义custom的toast参数为false的话,默认对报错进行toast弹出提示
  82 + if (custom.toast !== false) {
  83 + uni.$u.toast(data.message || data.msg);
  84 + }
  85 + // 如果需要catch返回,则进行reject
  86 + if (custom?.catch) {
  87 + return Promise.reject(data);
  88 + } else {
  89 + // 否则返回一个pending中的promise,请求不会进入catch中
  90 + return new Promise(() => {});
  91 + }
  92 + }
  93 + },
  94 + (response) => {
  95 + // 关闭加载动画
  96 + store.commit("setLoadingShow", false);
  97 + // 对响应错误做点什么 (statusCode !== 200)
  98 + let errorData = "请检查网络或服务器";
  99 + let message = response.data?.message || response?.errMsg;
  100 + if (message == "request:fail url not in domain list") {
  101 + errorData = "检查请求域名是否添加了域名白名单";
  102 + } else if (message == "request:fail timeout") {
  103 + errorData = "请求超时:请检查网络";
  104 + } else if (message == "Token has expired") {
  105 + errorData = "Token失效,请重新登录";
  106 + uni.reLaunch({
  107 + url: "/publicLoginSubPage/public/login",
  108 + });
  109 + store.commit("emptyUserInfo");
  110 + } else if (message == "Invalid username or password") {
  111 + errorData = "用户名或者密码无效";
  112 + uni.reLaunch({
  113 + url: "/publicLoginSubPage/public/login",
  114 + });
  115 + store.commit("emptyUserInfo");
  116 + } else {
  117 + errorData = message || "请检查网络或服务器";
  118 + }
  119 + uni.$u.toast(errorData);
  120 + return Promise.reject(response);
  121 + }
  122 +);
1 -<template>  
2 - <view class="device-detail-page">  
3 - <!-- 公共组件-每个页面必须引入 -->  
4 - <public-module></public-module>  
5 - <u-sticky bgColor="#fff"><u-tabs :list="list" :current="currentTab" @click="handleTabClick"></u-tabs></u-sticky>  
6 - <view style="margin-top:30rpx;">  
7 - <basicInfo v-if="currentTab == 0" :deviceDetail="deviceDetail" />  
8 - <realTimeData v-if="currentTab === 1" />  
9 - <historyData v-if="currentTab === 2" :keys="keys" />  
10 - <alarmHistory v-if="currentTab === 3" />  
11 - <commondRecord v-if="currentTab === 4" />  
12 - </view>  
13 - <f-tabbar></f-tabbar>  
14 - </view>  
15 -</template>  
16 -  
17 -<script>  
18 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
19 -import basicInfo from './tabDetail/basicInfo.vue';  
20 -import realTimeData from './tabDetail/realtimeData.vue';  
21 -import alarmHistory from './tabDetail/alarmHistory.vue';  
22 -import historyData from './tabDetail/historyData.vue';  
23 -import commondRecord from './tabDetail/commondRecord.vue';  
24 -import { getDeviceKeys } from './api/index.js';  
25 -export default {  
26 - components: {  
27 - fTabbar,  
28 - basicInfo,  
29 - realTimeData,  
30 - alarmHistory,  
31 - historyData,  
32 - commondRecord  
33 - },  
34 - data() {  
35 - return {  
36 - list: [{ name: '基础信息' }, { name: '实时数据' }, { name: '历史数据' }, { name: '告警记录' }, { name: '命令记录' }],  
37 - currentTab: 0,  
38 - id: '',  
39 - deviceDetail: {},  
40 - keys:[]  
41 - };  
42 - },  
43 - async onLoad(options) {  
44 - const { id, alarmStatus, lastOnlineTime, tbDeviceId } = options;  
45 - const res = await uni.$u.http.get(`/yt/device/${id}`);  
46 - this.deviceDetail = { ...res, alarmStatus, lastOnlineTime };  
47 -  
48 - // var socketTask = uni.connectSocket({  
49 - // url: 'wss://dev.thingskit.com:8080/api/ws/plugins/telemetry?token=' + uni.getStorageSync('userInfo').isToken, //仅为示例,并非真实接口地址。  
50 - // complete: ()=> {}  
51 - // });  
52 - // uni.onSocketOpen((header)=>{  
53 - // console.log('连接成功',header)  
54 - // })  
55 - // // socketTask.onMessage(function(data) {  
56 - // // console.log('收到消息了', data);  
57 - // // });  
58 - // socketTask.send({  
59 - // data: JSON.stringify({  
60 - // attrSubCmds: [],  
61 - // tsSubCmds: [  
62 - // {  
63 - // entityType: 'DEVICE',  
64 - // entityId: id,  
65 - // scope: 'LATEST_TELEMETRY',  
66 - // cmdId: 1  
67 - // }  
68 - // ],  
69 - // historyCmds: [],  
70 - // entityDataCmds: [],  
71 - // entityDataUnsubscribeCmds: [],  
72 - // alarmDataCmds: [],  
73 - // alarmDataUnsubscribeCmds: [],  
74 - // entityCountCmds: [],  
75 - // entityCountUnsubscribeCmds: []  
76 - // }),  
77 - // success() {  
78 - // console.log('发送成功了');  
79 - // }  
80 - // });  
81 -  
82 -  
83 - const keys = await getDeviceKeys(tbDeviceId);  
84 - // 隐藏原生的tabbar'  
85 - this.keys = [keys]  
86 - uni.hideTabBar();  
87 - },  
88 - methods: {  
89 - handleTabClick({ index }) {  
90 - this.currentTab = index;  
91 - }  
92 - }  
93 -}; 1 +<template>
  2 + <view class="device-detail-page">
  3 + <!-- 公共组件-每个页面必须引入 -->
  4 + <public-module></public-module>
  5 + <u-sticky bgColor="#fff"><u-tabs :list="list" :current="currentTab" @click="handleTabClick"></u-tabs></u-sticky>
  6 + <view style="margin-top:30rpx;">
  7 + <basicInfo v-if="currentTab == 0" :deviceDetail="deviceDetail" />
  8 + <realTimeData v-if="currentTab === 1" />
  9 + <historyData v-if="currentTab === 2" :keys="keys" />
  10 + <alarmHistory v-if="currentTab === 3" />
  11 + <commondRecord v-if="currentTab === 4" />
  12 + </view>
  13 + <f-tabbar></f-tabbar>
  14 + </view>
  15 +</template>
  16 +
  17 +<script>
  18 +import fTabbar from '@/components/module/f-tabbar/f-tabbar';
  19 +import basicInfo from './tabDetail/basicInfo.vue';
  20 +import realTimeData from './tabDetail/realtimeData.vue';
  21 +import alarmHistory from './tabDetail/alarmHistory.vue';
  22 +import historyData from './tabDetail/historyData.vue';
  23 +import commondRecord from './tabDetail/commondRecord.vue';
  24 +import { getDeviceKeys } from '../../pages/device/api/index';
  25 +export default {
  26 + components: {
  27 + fTabbar,
  28 + basicInfo,
  29 + realTimeData,
  30 + alarmHistory,
  31 + historyData,
  32 + commondRecord
  33 + },
  34 + data() {
  35 + return {
  36 + list: [{ name: '基础信息' }, { name: '实时数据' }, { name: '历史数据' }, { name: '告警记录' }, { name: '命令记录' }],
  37 + currentTab: 0,
  38 + id: '',
  39 + deviceDetail: {},
  40 + keys:[]
  41 + };
  42 + },
  43 + async onLoad(options) {
  44 + const { id, alarmStatus, lastOnlineTime, tbDeviceId } = options;
  45 + const res = await uni.$u.http.get(`/yt/device/${id}`);
  46 + this.deviceDetail = { ...res, alarmStatus, lastOnlineTime };
  47 +
  48 + // var socketTask = uni.connectSocket({
  49 + // url: 'wss://dev.thingskit.com:8080/api/ws/plugins/telemetry?token=' + uni.getStorageSync('userInfo').isToken, //仅为示例,并非真实接口地址。
  50 + // complete: ()=> {}
  51 + // });
  52 + // uni.onSocketOpen((header)=>{
  53 + // console.log('连接成功',header)
  54 + // })
  55 + // // socketTask.onMessage(function(data) {
  56 + // // console.log('收到消息了', data);
  57 + // // });
  58 + // socketTask.send({
  59 + // data: JSON.stringify({
  60 + // attrSubCmds: [],
  61 + // tsSubCmds: [
  62 + // {
  63 + // entityType: 'DEVICE',
  64 + // entityId: id,
  65 + // scope: 'LATEST_TELEMETRY',
  66 + // cmdId: 1
  67 + // }
  68 + // ],
  69 + // historyCmds: [],
  70 + // entityDataCmds: [],
  71 + // entityDataUnsubscribeCmds: [],
  72 + // alarmDataCmds: [],
  73 + // alarmDataUnsubscribeCmds: [],
  74 + // entityCountCmds: [],
  75 + // entityCountUnsubscribeCmds: []
  76 + // }),
  77 + // success() {
  78 + // console.log('发送成功了');
  79 + // }
  80 + // });
  81 +
  82 +
  83 + const keys = await getDeviceKeys(tbDeviceId);
  84 + // 隐藏原生的tabbar'
  85 + this.keys = [keys]
  86 + uni.hideTabBar();
  87 + },
  88 + methods: {
  89 + handleTabClick({ index }) {
  90 + this.currentTab = index;
  91 + }
  92 + }
  93 +};
94 </script> 94 </script>
deviceSubPage/deviceDetailPage/tabDetail/alarmHistory.vue renamed from pages/device/tabDetail/alarmHistory.vue
1 -<template>  
2 - <view class="alert-page">  
3 - <!-- 公共组件-每个页面必须引入 -->  
4 - <public-module></public-module>  
5 - <view style="width: 192rpx;margin: 19rpx;"><u-button @click="openSearchDialog" shape="circle" type="info" icon="search" text="筛选"></u-button></view>  
6 - <view class="device-list">  
7 - <view @click="openDeviceDetail(item.id)" class="list-item" v-for="(item, index) in list" :key="index">  
8 - <view class="u-flex item" style="justify-content: flex-start;flex-direction: column;align-items: center;">  
9 - <view style="width: 400rpx;text-align: left;">  
10 - <text style="color:#333;font-size: 15px;">{{ item.name1 }}</text>  
11 - </view>  
12 - <view style="width: 400rpx;text-align: left;">  
13 - <text style="color:#666;font-size: 15px;">{{ item.name2 }}</text>  
14 - </view>  
15 - <view style="width: 400rpx;text-align: left;">  
16 - <text style="color:#666;font-size: 15px;">{{ item.name3 }}</text>  
17 - </view>  
18 - <view style="width: 400rpx;text-align: left;">  
19 - <text style="color:#999;font-size: 15px;">{{ item.time }}</text>  
20 - </view>  
21 - </view>  
22 - <view class="item">  
23 - <view class="u-flex" style="margin-top: -6rpx;">  
24 - <image style="width: 30rpx;height: 30rpx;margin-top: 5rpx;margin-right: 5rpx;" :src="item.name4" mode=""></image>  
25 - <view>  
26 - <text style="color: #377DFF;font-size: 13px;margin-left: 5rpx;margin-top: 20rpx;">{{ item.name5 }}</text>  
27 - </view>  
28 - </view>  
29 - </view>  
30 - </view>  
31 - </view>  
32 - <view style="height: 30rpx;"></view>  
33 - <!-- 告警筛选 -->  
34 - <u-popup @close="close" closeable bgColor="transparent" :overlay="true" :show="show" mode="bottom">  
35 - <view style="height: 1100rpx;background:#fff;border-radius: 20rpx;overflow-y: scroll;">  
36 - <view style="text-align: center;position: relative;top: 68rpx;margin-top: -40rpx;"><text style="font-size: 16px;color: #333333;">筛选条件</text></view>  
37 - <view style="margin-top: 97rpx;margin-left: 43rpx;">  
38 - <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333333;font-size: 14px;">告警状态</text></view>  
39 - <view  
40 - class="u-flex"  
41 - style="margin-top: 15rpx;width:650rpx;height: 60rpx;  
42 - flex-wrap: wrap;justify-content: space-between; align-content: space-between;"  
43 - >  
44 - <view  
45 - v-for="(item, index) in alertStatus"  
46 - :key="index"  
47 - style="margin: 10rpx;line-height: 50rpx;text-align: center;  
48 - width:180rpx;height: 60rpx;  
49 - background-color:#F6F6F6;border-radius:32px"  
50 - >  
51 - <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>  
52 - </view>  
53 - </view>  
54 - </view>  
55 - <view style="margin-top: 145rpx;margin-left: 43rpx;">  
56 - <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333333;font-size: 14px;">设备类型</text></view>  
57 - <view  
58 - class="u-flex"  
59 - style="margin-top: 15rpx;width:650rpx;height: 60rpx;  
60 - flex-wrap: wrap;justify-content: space-between; align-content: space-between;"  
61 - >  
62 - <view  
63 - v-for="(item, index) in deviceType"  
64 - :key="index"  
65 - style="margin: 10rpx;line-height: 50rpx;text-align: center;  
66 - width:180rpx;height: 60rpx;  
67 - background-color:#F6F6F6;border-radius:32px"  
68 - >  
69 - <text style="color:#333;font-size: 13px;">{{ item.name }}</text>  
70 - </view>  
71 - </view>  
72 - </view>  
73 - <view style="margin-top: 136rpx;margin-left: 43rpx;">  
74 - <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333;font-size: 14px;">告警等级</text></view>  
75 - <view  
76 - class="u-flex"  
77 - style="margin-top: 15rpx;width:650rpx;height: 60rpx;  
78 - flex-wrap: wrap;justify-content: space-between; align-content: space-between;"  
79 - >  
80 - <view  
81 - v-for="(item, index) in alertLevel"  
82 - :key="index"  
83 - style="margin: 10rpx;line-height: 50rpx;text-align: center;  
84 - width:180rpx;height: 60rpx;  
85 - background-color:#F6F6F6;border-radius:32px"  
86 - >  
87 - <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>  
88 - </view>  
89 - </view>  
90 - </view>  
91 - <view style="margin-top: 136rpx;margin-left: 43rpx;">  
92 - <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333333;font-size: 14px;">选择时间</text></view>  
93 - <view  
94 - class="u-flex"  
95 - style="margin-top: 15rpx;width:650rpx;height: 60rpx;  
96 - flex-wrap: wrap;justify-content: space-between; align-content: space-between;"  
97 - >  
98 - <view  
99 - v-for="(item, index) in timeArea"  
100 - :key="index"  
101 - style="margin: 10rpx;line-height: 50rpx;text-align: center;  
102 - width:180rpx;height: 60rpx;  
103 - background-color:#F6F6F6;border-radius:32px"  
104 - >  
105 - <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>  
106 - </view>  
107 - </view>  
108 - </view>  
109 - <view style="margin-top: 136rpx;margin-left: 43rpx;">  
110 - <view class="u-flex" style="margin-left: 10rpx;margin-top: 15rpx;width:750rpx;height: 60rpx;">  
111 - <u--form labelPosition="left" :model="timeData" :rules="rules" ref="form1" style="padding-left: 26rpx;width: 617rpx!important;">  
112 - <u-form-item  
113 - style="font-size: 14px;"  
114 - label="选择日期"  
115 - prop="selectTime"  
116 - labelWidth="80"  
117 - borderBottom  
118 - @click="  
119 - showCalendar = true;  
120 - hideKeyboard();  
121 - "  
122 - >  
123 - <u--input v-model="timeData.selectTime" placeholder="请选择日期" border="none"></u--input>  
124 - </u-form-item>  
125 - </u--form>  
126 - </view>  
127 - </view>  
128 - <view class="u-flex" style="margin-top: 128rpx;margin-left: 55rpx;">  
129 - <view style="width: 300rpx"><u-button type="info" shape="circle" text="重置"></u-button></view>  
130 - <view style="width: 300rpx;margin-left:46rpx ;"><u-button type="primary" shape="circle" text="确认"></u-button></view>  
131 - </view>  
132 - <view style="height: 30rpx;"></view>  
133 - </view>  
134 - </u-popup>  
135 - <u-calendar  
136 - :show="showCalendar"  
137 - mode="range"  
138 - @confirm="calendarConfirm"  
139 - @close="calendarClose"  
140 - startText="开始时间"  
141 - endText="结束时间"  
142 - confirmDisabledText="请选择日期"  
143 - :formatter="formatter"  
144 - ></u-calendar>  
145 - <f-tabbar :isFillHeight="false"></f-tabbar>  
146 - </view>  
147 -</template>  
148 -  
149 -<script>  
150 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
151 -export default {  
152 - components: {  
153 - fTabbar  
154 - },  
155 - data() {  
156 - return {  
157 - show: false,  
158 - timeData: {  
159 - selectTime: '',  
160 - getTimeGap: ''  
161 - },  
162 - showCalendar: false,  
163 - alertStatus: [  
164 - {  
165 - index: 1,  
166 - name: '全部',  
167 - bgColor: '#377DFF',  
168 - textColor: '#377DFF'  
169 - },  
170 - {  
171 - index: 2,  
172 - name: '激活未确认',  
173 - bgColor: '#F6F6F6',  
174 - textColor: '#F6F6F6'  
175 - },  
176 - {  
177 - index: 3,  
178 - name: '激活已确认',  
179 - bgColor: '#F6F6F6',  
180 - textColor: '#F6F6F6'  
181 - },  
182 - {  
183 - index: 4,  
184 - name: '清除未确认',  
185 - bgColor: '#F6F6F6',  
186 - textColor: '#F6F6F6'  
187 - },  
188 - {  
189 - index: 5,  
190 - name: '清除已确认',  
191 - bgColor: '#F6F6F6',  
192 - textColor: '#F6F6F6'  
193 - },  
194 - {  
195 - index: 6,  
196 - name: '清除已确认',  
197 - bgColor: '#F6F6F6',  
198 - textColor: '#F6F6F6'  
199 - }  
200 - ],  
201 - deviceType: [  
202 - {  
203 - index: 1,  
204 - name: '全部',  
205 - bgColor: '#377DFF',  
206 - textColor: '#377DFF'  
207 - },  
208 - {  
209 - index: 2,  
210 - name: '网关设备',  
211 - bgColor: '#F6F6F6',  
212 - textColor: '#F6F6F6'  
213 - },  
214 - {  
215 - index: 3,  
216 - name: '网关子设备',  
217 - bgColor: '#F6F6F6',  
218 - textColor: '#F6F6F6'  
219 - },  
220 - {  
221 - index: 4,  
222 - name: '直连设备',  
223 - bgColor: '#F6F6F6',  
224 - textColor: '#F6F6F6'  
225 - }  
226 - ],  
227 - alertLevel: [  
228 - {  
229 - index: 1,  
230 - name: '全部',  
231 - bgColor: '#377DFF',  
232 - textColor: '#377DFF'  
233 - },  
234 - {  
235 - index: 2,  
236 - name: '危险',  
237 - bgColor: '#F6F6F6',  
238 - textColor: '#F6F6F6'  
239 - },  
240 - {  
241 - index: 3,  
242 - name: '重要',  
243 - bgColor: '#F6F6F6',  
244 - textColor: '#F6F6F6'  
245 - },  
246 - {  
247 - index: 4,  
248 - name: '次要',  
249 - bgColor: '#F6F6F6',  
250 - textColor: '#F6F6F6'  
251 - },  
252 - {  
253 - index: 4,  
254 - name: '警告',  
255 - bgColor: '#F6F6F6',  
256 - textColor: '#F6F6F6'  
257 - },  
258 - {  
259 - index: 4,  
260 - name: '不确定',  
261 - bgColor: '#F6F6F6',  
262 - textColor: '#F6F6F6'  
263 - }  
264 - ],  
265 - timeArea: [  
266 - {  
267 - index: 1,  
268 - name: '全部',  
269 - value: '全部',  
270 - bgColor: '#F6F6F6',  
271 - textColor: '#F6F6F6'  
272 - },  
273 - {  
274 - index: 2,  
275 - name: '30分钟',  
276 - value: '30',  
277 - bgColor: '#F6F6F6',  
278 - textColor: '#F6F6F6'  
279 - },  
280 - {  
281 - index: 3,  
282 - name: '1小时',  
283 - value: '30',  
284 - bgColor: '#F6F6F6',  
285 - textColor: '#F6F6F6'  
286 - },  
287 - {  
288 - index: 4,  
289 - name: '2小时',  
290 - value: '120',  
291 - bgColor: '#F6F6F6',  
292 - textColor: '#F6F6F6'  
293 - },  
294 - {  
295 - index: 5,  
296 - name: '近一天',  
297 - value: '24',  
298 - bgColor: '#F6F6F6',  
299 - textColor: '#F6F6F6'  
300 - },  
301 - {  
302 - index: 6,  
303 - name: '',  
304 - value: '',  
305 - bgColor: '#F6F6F6',  
306 - textColor: '#F6F6F6'  
307 - }  
308 - ],  
309 - list: [  
310 - {  
311 - name1: '1号楼1楼三单元水表',  
312 - name2: 'CO₂:65.32',  
313 - name3: '告警状态:清除已确认',  
314 - name4: '../../../static/danger.png',  
315 - name5: '危险',  
316 - time: '2022-04-01 02:12:23',  
317 - id: 'xx1'  
318 - },  
319 - {  
320 - name1: '2号楼1楼三单元水表',  
321 - name2: 'PH:9.8',  
322 - name3: '告警状态:激活未确认',  
323 - name4: '../../../static/major.png',  
324 - name5: '重要',  
325 - time: '2022-04-01 02:12:23',  
326 - id: 'xx2'  
327 - },  
328 - {  
329 - name1: '3号楼1楼三单元水表',  
330 - name2: 'NH3:600',  
331 - name3: '告警状态:激活未确认',  
332 - name4: '../../../static/secondary.png',  
333 - name5: '次要',  
334 - time: '2022-04-01 02:12:23',  
335 - id: 'xx3'  
336 - },  
337 - {  
338 - name1: '4号楼1楼三单元水表',  
339 - name2: '水深:1.4',  
340 - name3: '告警状态:激活未确认',  
341 - name4: '../../../static/secondary.png',  
342 - name5: '次要',  
343 - time: '2022-04-01 02:12:23',  
344 - id: 'xx4'  
345 - },  
346 - {  
347 - name1: '5号楼1楼三单元水表',  
348 - name2: 'COD:125',  
349 - name3: '告警状态:激活未确认',  
350 - name4: '../../../static/noshue.png',  
351 - name5: '不确定',  
352 - time: '2022-04-01 02:12:23',  
353 - id: 'xx5'  
354 - }  
355 - ]  
356 - };  
357 - },  
358 - onLoad(e) {  
359 - // 隐藏原生的tabbar  
360 - uni.hideTabBar();  
361 - },  
362 - methods: {  
363 - open() {},  
364 - close() {  
365 - this.show = false;  
366 - },  
367 - openSearchDialog() {  
368 - this.show = true;  
369 - },  
370 - hideKeyboard() {  
371 - uni.hideKeyboard();  
372 - },  
373 - calendarConfirm(e) {  
374 - this.showCalendar = false;  
375 - this.timeData.selectTime = `${e[0]} / ${e[e.length - 1]}`;  
376 - },  
377 - calendarClose() {  
378 - this.showCalendar = false;  
379 - }  
380 - }  
381 -};  
382 -</script>  
383 -  
384 -<style lang="scss" scoped>  
385 -.alert-page {  
386 - margin-top: -39rpx;  
387 -}  
388 -.device-list {  
389 - display: flex;  
390 - flex-direction: column;  
391 - padding-left: 18rpx;  
392 - margin-top: -18rpx;  
393 - .list-item {  
394 - width: 713rpx;  
395 - height: 233rpx;  
396 - background-color: #fff;  
397 - margin-top: 24rpx;  
398 - display: flex;  
399 -  
400 - border-radius: 10px;  
401 - justify-content: space-between;  
402 - .item {  
403 - margin: 30rpx;  
404 - }  
405 - }  
406 -} 1 +<template>
  2 + <view class="alert-page">
  3 + <!-- 公共组件-每个页面必须引入 -->
  4 + <public-module></public-module>
  5 + <view style="width: 192rpx;margin: 19rpx;"><u-button @click="openSearchDialog" shape="circle" type="info" icon="search" text="筛选"></u-button></view>
  6 + <view class="device-list">
  7 + <view @click="openDeviceDetail(item.id)" class="list-item" v-for="(item, index) in list" :key="index">
  8 + <view class="u-flex item" style="justify-content: flex-start;flex-direction: column;align-items: center;">
  9 + <view style="width: 400rpx;text-align: left;">
  10 + <text style="color:#333;font-size: 15px;">{{ item.name1 }}</text>
  11 + </view>
  12 + <view style="width: 400rpx;text-align: left;">
  13 + <text style="color:#666;font-size: 15px;">{{ item.name2 }}</text>
  14 + </view>
  15 + <view style="width: 400rpx;text-align: left;">
  16 + <text style="color:#666;font-size: 15px;">{{ item.name3 }}</text>
  17 + </view>
  18 + <view style="width: 400rpx;text-align: left;">
  19 + <text style="color:#999;font-size: 15px;">{{ item.time }}</text>
  20 + </view>
  21 + </view>
  22 + <view class="item">
  23 + <view class="u-flex" style="margin-top: -6rpx;">
  24 + <image style="width: 30rpx;height: 30rpx;margin-top: 5rpx;margin-right: 5rpx;" :src="item.name4" mode=""></image>
  25 + <view>
  26 + <text style="color: #377DFF;font-size: 13px;margin-left: 5rpx;margin-top: 20rpx;">{{ item.name5 }}</text>
  27 + </view>
  28 + </view>
  29 + </view>
  30 + </view>
  31 + </view>
  32 + <view style="height: 30rpx;"></view>
  33 + <!-- 告警筛选 -->
  34 + <u-popup @close="close" closeable bgColor="transparent" :overlay="true" :show="show" mode="bottom">
  35 + <view style="height: 1100rpx;background:#fff;border-radius: 20rpx;overflow-y: scroll;">
  36 + <view style="text-align: center;position: relative;top: 68rpx;margin-top: -40rpx;"><text style="font-size: 16px;color: #333333;">筛选条件</text></view>
  37 + <view style="margin-top: 97rpx;margin-left: 43rpx;">
  38 + <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333333;font-size: 14px;">告警状态</text></view>
  39 + <view
  40 + class="u-flex"
  41 + style="margin-top: 15rpx;width:650rpx;height: 60rpx;
  42 + flex-wrap: wrap;justify-content: space-between; align-content: space-between;"
  43 + >
  44 + <view
  45 + v-for="(item, index) in alertStatus"
  46 + :key="index"
  47 + style="margin: 10rpx;line-height: 50rpx;text-align: center;
  48 + width:180rpx;height: 60rpx;
  49 + background-color:#F6F6F6;border-radius:32px"
  50 + >
  51 + <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>
  52 + </view>
  53 + </view>
  54 + </view>
  55 + <view style="margin-top: 145rpx;margin-left: 43rpx;">
  56 + <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333333;font-size: 14px;">设备类型</text></view>
  57 + <view
  58 + class="u-flex"
  59 + style="margin-top: 15rpx;width:650rpx;height: 60rpx;
  60 + flex-wrap: wrap;justify-content: space-between; align-content: space-between;"
  61 + >
  62 + <view
  63 + v-for="(item, index) in deviceType"
  64 + :key="index"
  65 + style="margin: 10rpx;line-height: 50rpx;text-align: center;
  66 + width:180rpx;height: 60rpx;
  67 + background-color:#F6F6F6;border-radius:32px"
  68 + >
  69 + <text style="color:#333;font-size: 13px;">{{ item.name }}</text>
  70 + </view>
  71 + </view>
  72 + </view>
  73 + <view style="margin-top: 136rpx;margin-left: 43rpx;">
  74 + <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333;font-size: 14px;">告警等级</text></view>
  75 + <view
  76 + class="u-flex"
  77 + style="margin-top: 15rpx;width:650rpx;height: 60rpx;
  78 + flex-wrap: wrap;justify-content: space-between; align-content: space-between;"
  79 + >
  80 + <view
  81 + v-for="(item, index) in alertLevel"
  82 + :key="index"
  83 + style="margin: 10rpx;line-height: 50rpx;text-align: center;
  84 + width:180rpx;height: 60rpx;
  85 + background-color:#F6F6F6;border-radius:32px"
  86 + >
  87 + <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>
  88 + </view>
  89 + </view>
  90 + </view>
  91 + <view style="margin-top: 136rpx;margin-left: 43rpx;">
  92 + <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333333;font-size: 14px;">选择时间</text></view>
  93 + <view
  94 + class="u-flex"
  95 + style="margin-top: 15rpx;width:650rpx;height: 60rpx;
  96 + flex-wrap: wrap;justify-content: space-between; align-content: space-between;"
  97 + >
  98 + <view
  99 + v-for="(item, index) in timeArea"
  100 + :key="index"
  101 + style="margin: 10rpx;line-height: 50rpx;text-align: center;
  102 + width:180rpx;height: 60rpx;
  103 + background-color:#F6F6F6;border-radius:32px"
  104 + >
  105 + <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>
  106 + </view>
  107 + </view>
  108 + </view>
  109 + <view style="margin-top: 136rpx;margin-left: 43rpx;">
  110 + <view class="u-flex" style="margin-left: 10rpx;margin-top: 15rpx;width:750rpx;height: 60rpx;">
  111 + <u--form labelPosition="left" :model="timeData" :rules="rules" ref="form1" style="padding-left: 26rpx;width: 617rpx!important;">
  112 + <u-form-item
  113 + style="font-size: 14px;"
  114 + label="选择日期"
  115 + prop="selectTime"
  116 + labelWidth="80"
  117 + borderBottom
  118 + @click="
  119 + showCalendar = true;
  120 + hideKeyboard();
  121 + "
  122 + >
  123 + <u--input v-model="timeData.selectTime" placeholder="请选择日期" border="none"></u--input>
  124 + </u-form-item>
  125 + </u--form>
  126 + </view>
  127 + </view>
  128 + <view class="u-flex" style="margin-top: 128rpx;margin-left: 55rpx;">
  129 + <view style="width: 300rpx"><u-button type="info" shape="circle" text="重置"></u-button></view>
  130 + <view style="width: 300rpx;margin-left:46rpx ;"><u-button type="primary" shape="circle" text="确认"></u-button></view>
  131 + </view>
  132 + <view style="height: 30rpx;"></view>
  133 + </view>
  134 + </u-popup>
  135 + <u-calendar
  136 + :show="showCalendar"
  137 + mode="range"
  138 + @confirm="calendarConfirm"
  139 + @close="calendarClose"
  140 + startText="开始时间"
  141 + endText="结束时间"
  142 + confirmDisabledText="请选择日期"
  143 + :formatter="formatter"
  144 + ></u-calendar>
  145 + <f-tabbar :isFillHeight="false"></f-tabbar>
  146 + </view>
  147 +</template>
  148 +
  149 +<script>
  150 +import fTabbar from '@/components/module/f-tabbar/f-tabbar';
  151 +export default {
  152 + components: {
  153 + fTabbar
  154 + },
  155 + data() {
  156 + return {
  157 + show: false,
  158 + timeData: {
  159 + selectTime: '',
  160 + getTimeGap: ''
  161 + },
  162 + showCalendar: false,
  163 + alertStatus: [
  164 + {
  165 + index: 1,
  166 + name: '全部',
  167 + bgColor: '#377DFF',
  168 + textColor: '#377DFF'
  169 + },
  170 + {
  171 + index: 2,
  172 + name: '激活未确认',
  173 + bgColor: '#F6F6F6',
  174 + textColor: '#F6F6F6'
  175 + },
  176 + {
  177 + index: 3,
  178 + name: '激活已确认',
  179 + bgColor: '#F6F6F6',
  180 + textColor: '#F6F6F6'
  181 + },
  182 + {
  183 + index: 4,
  184 + name: '清除未确认',
  185 + bgColor: '#F6F6F6',
  186 + textColor: '#F6F6F6'
  187 + },
  188 + {
  189 + index: 5,
  190 + name: '清除已确认',
  191 + bgColor: '#F6F6F6',
  192 + textColor: '#F6F6F6'
  193 + },
  194 + {
  195 + index: 6,
  196 + name: '清除已确认',
  197 + bgColor: '#F6F6F6',
  198 + textColor: '#F6F6F6'
  199 + }
  200 + ],
  201 + deviceType: [
  202 + {
  203 + index: 1,
  204 + name: '全部',
  205 + bgColor: '#377DFF',
  206 + textColor: '#377DFF'
  207 + },
  208 + {
  209 + index: 2,
  210 + name: '网关设备',
  211 + bgColor: '#F6F6F6',
  212 + textColor: '#F6F6F6'
  213 + },
  214 + {
  215 + index: 3,
  216 + name: '网关子设备',
  217 + bgColor: '#F6F6F6',
  218 + textColor: '#F6F6F6'
  219 + },
  220 + {
  221 + index: 4,
  222 + name: '直连设备',
  223 + bgColor: '#F6F6F6',
  224 + textColor: '#F6F6F6'
  225 + }
  226 + ],
  227 + alertLevel: [
  228 + {
  229 + index: 1,
  230 + name: '全部',
  231 + bgColor: '#377DFF',
  232 + textColor: '#377DFF'
  233 + },
  234 + {
  235 + index: 2,
  236 + name: '危险',
  237 + bgColor: '#F6F6F6',
  238 + textColor: '#F6F6F6'
  239 + },
  240 + {
  241 + index: 3,
  242 + name: '重要',
  243 + bgColor: '#F6F6F6',
  244 + textColor: '#F6F6F6'
  245 + },
  246 + {
  247 + index: 4,
  248 + name: '次要',
  249 + bgColor: '#F6F6F6',
  250 + textColor: '#F6F6F6'
  251 + },
  252 + {
  253 + index: 4,
  254 + name: '警告',
  255 + bgColor: '#F6F6F6',
  256 + textColor: '#F6F6F6'
  257 + },
  258 + {
  259 + index: 4,
  260 + name: '不确定',
  261 + bgColor: '#F6F6F6',
  262 + textColor: '#F6F6F6'
  263 + }
  264 + ],
  265 + timeArea: [
  266 + {
  267 + index: 1,
  268 + name: '全部',
  269 + value: '全部',
  270 + bgColor: '#F6F6F6',
  271 + textColor: '#F6F6F6'
  272 + },
  273 + {
  274 + index: 2,
  275 + name: '30分钟',
  276 + value: '30',
  277 + bgColor: '#F6F6F6',
  278 + textColor: '#F6F6F6'
  279 + },
  280 + {
  281 + index: 3,
  282 + name: '1小时',
  283 + value: '30',
  284 + bgColor: '#F6F6F6',
  285 + textColor: '#F6F6F6'
  286 + },
  287 + {
  288 + index: 4,
  289 + name: '2小时',
  290 + value: '120',
  291 + bgColor: '#F6F6F6',
  292 + textColor: '#F6F6F6'
  293 + },
  294 + {
  295 + index: 5,
  296 + name: '近一天',
  297 + value: '24',
  298 + bgColor: '#F6F6F6',
  299 + textColor: '#F6F6F6'
  300 + },
  301 + {
  302 + index: 6,
  303 + name: '',
  304 + value: '',
  305 + bgColor: '#F6F6F6',
  306 + textColor: '#F6F6F6'
  307 + }
  308 + ],
  309 + list: [
  310 + {
  311 + name1: '1号楼1楼三单元水表',
  312 + name2: 'CO₂:65.32',
  313 + name3: '告警状态:清除已确认',
  314 + name4: '../../../static/danger.png',
  315 + name5: '危险',
  316 + time: '2022-04-01 02:12:23',
  317 + id: 'xx1'
  318 + },
  319 + {
  320 + name1: '2号楼1楼三单元水表',
  321 + name2: 'PH:9.8',
  322 + name3: '告警状态:激活未确认',
  323 + name4: '../../../static/major.png',
  324 + name5: '重要',
  325 + time: '2022-04-01 02:12:23',
  326 + id: 'xx2'
  327 + },
  328 + {
  329 + name1: '3号楼1楼三单元水表',
  330 + name2: 'NH3:600',
  331 + name3: '告警状态:激活未确认',
  332 + name4: '../../../static/secondary.png',
  333 + name5: '次要',
  334 + time: '2022-04-01 02:12:23',
  335 + id: 'xx3'
  336 + },
  337 + {
  338 + name1: '4号楼1楼三单元水表',
  339 + name2: '水深:1.4',
  340 + name3: '告警状态:激活未确认',
  341 + name4: '../../../static/secondary.png',
  342 + name5: '次要',
  343 + time: '2022-04-01 02:12:23',
  344 + id: 'xx4'
  345 + },
  346 + {
  347 + name1: '5号楼1楼三单元水表',
  348 + name2: 'COD:125',
  349 + name3: '告警状态:激活未确认',
  350 + name4: '../../../static/noshue.png',
  351 + name5: '不确定',
  352 + time: '2022-04-01 02:12:23',
  353 + id: 'xx5'
  354 + }
  355 + ]
  356 + };
  357 + },
  358 + onLoad(e) {
  359 + // 隐藏原生的tabbar
  360 + uni.hideTabBar();
  361 + },
  362 + methods: {
  363 + open() {},
  364 + close() {
  365 + this.show = false;
  366 + },
  367 + openSearchDialog() {
  368 + this.show = true;
  369 + },
  370 + hideKeyboard() {
  371 + uni.hideKeyboard();
  372 + },
  373 + calendarConfirm(e) {
  374 + this.showCalendar = false;
  375 + this.timeData.selectTime = `${e[0]} / ${e[e.length - 1]}`;
  376 + },
  377 + calendarClose() {
  378 + this.showCalendar = false;
  379 + }
  380 + }
  381 +};
  382 +</script>
  383 +
  384 +<style lang="scss" scoped>
  385 +.alert-page {
  386 + margin-top: -39rpx;
  387 +}
  388 +.device-list {
  389 + display: flex;
  390 + flex-direction: column;
  391 + padding-left: 18rpx;
  392 + margin-top: -18rpx;
  393 + .list-item {
  394 + width: 713rpx;
  395 + height: 233rpx;
  396 + background-color: #fff;
  397 + margin-top: 24rpx;
  398 + display: flex;
  399 +
  400 + border-radius: 10px;
  401 + justify-content: space-between;
  402 + .item {
  403 + margin: 30rpx;
  404 + }
  405 + }
  406 +}
407 </style> 407 </style>
deviceSubPage/deviceDetailPage/tabDetail/basicInfo.vue renamed from pages/device/tabDetail/basicInfo.vue
1 -<template>  
2 - <view class="basic-page">  
3 - <!-- 公共组件-每个页面必须引入 -->  
4 - <public-module />  
5 - <view class="u-flex" style="justify-content: space-between;height: 140rpx;background-color: #fff;border-radius: 18px;">  
6 - <view class="u-flex">  
7 - <view style="margin-left: 20rpx;">  
8 - {{deviceDetail.name}}  
9 - </view>  
10 - <view style="margin-left: 20rpx; font-size: 14px;" :style="{color:deviceDetail.deviceState==='INACTIVE'?'#666':deviceDetail.deviceState==='ONLINE'?'#377DFF':'#DE4437'}">  
11 - {{deviceDetail.deviceState==='INACTIVE'?'未激活':deviceDetail.deviceState==='ONLINE'?'在线':'离线'}}  
12 - </view>  
13 - </view>  
14 - <view style="margin-right: 20rpx;">  
15 - <u-button type="primary" shape="circle" size="mini" text="下发命令" @click="showModal"/>  
16 - </view>  
17 - </view>  
18 - <view style="margin-top: 40rpx;height: 577rpx;background-color: #fff;border-radius: 20px;">  
19 - <u-list>  
20 - <u-list-item>  
21 -  
22 - <u-cell :title="deviceDetail.sn">  
23 - <view slot="icon">设备编号</view>  
24 - </u-cell>  
25 - </u-list-item>  
26 - <u-list-item>  
27 - <u-cell :title="deviceType">  
28 - <view slot="icon">设备类型</view>  
29 - </u-cell>  
30 - </u-list-item>  
31 - <u-list-item>  
32 - <u-cell :title="deviceDetail.organizationDTO.name">  
33 - <view slot="icon">所属组织</view>  
34 - </u-cell>  
35 - </u-list-item>  
36 - <u-list-item>  
37 - <u-cell :title="formatLastOnlineTime">  
38 - <view slot="icon">最后连接时间</view>  
39 - </u-cell>  
40 - </u-list-item>  
41 - <u-list-item>  
42 - <u-cell :title="alarmStatus">  
43 - <view slot="icon">是否告警</view>  
44 - </u-cell>  
45 - </u-list-ite>  
46 - <u-cell :title="deviceDetail.description">  
47 - <view slot="icon">设备描述</view>  
48 - </u-cell>  
49 - </u-list-item>  
50 - </u-list>  
51 - </view>  
52 - <!-- 下发指令 -->  
53 - <u-modal :show="showModel" title="命令下发" closeOnClickOverlay showCancelButton @close="hiddenModal" @cancel="hiddenModal" @confirm="handleConfirm" >  
54 - <u--textarea placeholder="请输入命令内容" v-model="formModel.intro" count />  
55 - </u-modal>  
56 - <f-tabbar />  
57 - </view>  
58 -</template>  
59 -  
60 -<script>  
61 -import {formatToDate} from '@/plugins/utils.js';  
62 -export default {  
63 - props:{  
64 - deviceDetail:{  
65 - type:Object,  
66 - default:()=>({}),  
67 - }  
68 - },  
69 - data() {  
70 - return {  
71 - showModel: false,  
72 - };  
73 - },  
74 - computed:{  
75 - deviceType(){  
76 - return this.deviceDetail.deviceType==='DIRECT_CONNECTION'?'直连设备':this.deviceDetail.deviceType==='GATEWAY'?'网关设备':this.deviceDetail.deviceType==='SENSOR'?'网关子设备':''  
77 - },  
78 - alarmStatus(){  
79 - return this.deviceDetail.alarmStatus === '0'?'否':'是'  
80 - },  
81 - formatLastOnlineTime(){  
82 - return formatToDate(Number(this.deviceDetail.lastOnlineTime),'YYYY-MM-DD HH:mm:ss')  
83 - }  
84 - },  
85 - onLoad(e) {  
86 - // 隐藏原生的tabbar  
87 - uni.hideTabBar();  
88 - },  
89 - onMounted(){  
90 - console.log(this.deviceDetail)  
91 -  
92 - },  
93 - methods: {  
94 - showModal() {  
95 - this.showModel = true;  
96 - },  
97 - hiddenModal(){  
98 - this.showModel = false;  
99 - },  
100 - handleConfirm(){  
101 - console.log('确定')  
102 - }  
103 - }  
104 -};  
105 -</script> 1 +<template>
  2 + <view class="basic-page">
  3 + <!-- 公共组件-每个页面必须引入 -->
  4 + <public-module />
  5 + <view class="u-flex" style="justify-content: space-between;height: 140rpx;background-color: #fff;border-radius: 18px;">
  6 + <view class="u-flex">
  7 + <view style="margin-left: 20rpx;">
  8 + {{deviceDetail.name}}
  9 + </view>
  10 + <view style="margin-left: 20rpx; font-size: 14px;" :style="{color:deviceDetail.deviceState==='INACTIVE'?'#666':deviceDetail.deviceState==='ONLINE'?'#377DFF':'#DE4437'}">
  11 + {{deviceDetail.deviceState==='INACTIVE'?'未激活':deviceDetail.deviceState==='ONLINE'?'在线':'离线'}}
  12 + </view>
  13 + </view>
  14 + <view style="margin-right: 20rpx;">
  15 + <u-button type="primary" shape="circle" size="mini" text="下发命令" @click="showModal"/>
  16 + </view>
  17 + </view>
  18 + <view style="margin-top: 40rpx;height: 577rpx;background-color: #fff;border-radius: 20px;">
  19 + <u-list>
  20 + <u-list-item>
  21 +
  22 + <u-cell :title="deviceDetail.sn">
  23 + <view slot="icon">设备编号</view>
  24 + </u-cell>
  25 + </u-list-item>
  26 + <u-list-item>
  27 + <u-cell :title="deviceType">
  28 + <view slot="icon">设备类型</view>
  29 + </u-cell>
  30 + </u-list-item>
  31 + <u-list-item>
  32 + <u-cell :title="deviceDetail.organizationDTO.name">
  33 + <view slot="icon">所属组织</view>
  34 + </u-cell>
  35 + </u-list-item>
  36 + <u-list-item>
  37 + <u-cell :title="formatLastOnlineTime">
  38 + <view slot="icon">最后连接时间</view>
  39 + </u-cell>
  40 + </u-list-item>
  41 + <u-list-item>
  42 + <u-cell :title="alarmStatus">
  43 + <view slot="icon">是否告警</view>
  44 + </u-cell>
  45 + </u-list-ite>
  46 + <u-cell :title="deviceDetail.description">
  47 + <view slot="icon">设备描述</view>
  48 + </u-cell>
  49 + </u-list-item>
  50 + </u-list>
  51 + </view>
  52 + <!-- 下发指令 -->
  53 + <u-modal :show="showModel" title="命令下发" closeOnClickOverlay showCancelButton @close="hiddenModal" @cancel="hiddenModal" @confirm="handleConfirm" >
  54 + <u--textarea placeholder="请输入命令内容" v-model="formModel.intro" count />
  55 + </u-modal>
  56 + <f-tabbar />
  57 + </view>
  58 +</template>
  59 +
  60 +<script>
  61 +import {formatToDate} from '@/plugins/utils.js';
  62 +export default {
  63 + props:{
  64 + deviceDetail:{
  65 + type:Object,
  66 + default:()=>({}),
  67 + }
  68 + },
  69 + data() {
  70 + return {
  71 + showModel: false,
  72 + };
  73 + },
  74 + computed:{
  75 + deviceType(){
  76 + return this.deviceDetail.deviceType==='DIRECT_CONNECTION'?'直连设备':this.deviceDetail.deviceType==='GATEWAY'?'网关设备':this.deviceDetail.deviceType==='SENSOR'?'网关子设备':''
  77 + },
  78 + alarmStatus(){
  79 + return this.deviceDetail.alarmStatus === '0'?'否':'是'
  80 + },
  81 + formatLastOnlineTime(){
  82 + return formatToDate(Number(this.deviceDetail.lastOnlineTime),'YYYY-MM-DD HH:mm:ss')
  83 + }
  84 + },
  85 + onLoad(e) {
  86 + // 隐藏原生的tabbar
  87 + uni.hideTabBar();
  88 + },
  89 + onMounted(){
  90 + console.log(this.deviceDetail)
  91 +
  92 + },
  93 + methods: {
  94 + showModal() {
  95 + this.showModel = true;
  96 + },
  97 + hiddenModal(){
  98 + this.showModel = false;
  99 + },
  100 + handleConfirm(){
  101 + console.log('确定')
  102 + }
  103 + }
  104 +};
  105 +</script>
deviceSubPage/deviceDetailPage/tabDetail/commondRecord.vue renamed from pages/device/tabDetail/commondRecord.vue
deviceSubPage/deviceDetailPage/tabDetail/historyData.vue renamed from pages/device/tabDetail/historyData.vue
1 -<template>  
2 - <view class="historyData">  
3 - <!-- 公共组件-每个页面必须引入 -->  
4 - <public-module></public-module>  
5 - <view class="historyData-top">  
6 - <u-form :label-style="{ 'font-size': '0rpx' }">  
7 - <u-form-item @click="openCalendar">  
8 - <u-input v-model="timeData.selectTime" disabled disabledColor="#fff" placeholder="请选择日期" border="none">  
9 - <template slot="prefix">  
10 - <image class="icon" src="../../../static/can-der.png"></image>  
11 - </template>  
12 - </u-input>  
13 - </u-form-item>  
14 - <u-form-item @click="openTimeGap">  
15 - <u-input v-model="timeData.getTimeGap" disabled disabledColor="#fff" placeholder="请选择时间区间" border="none">  
16 - <template slot="prefix">  
17 - <image class="icon" src="../../../static/time.png"></image>  
18 - </template>  
19 - </u-input>  
20 - </u-form-item>  
21 - <u-form-item @click="openType"><u-input shape="circle" v-model="timeData.getType" placeholder="请选择属性" disabled disabledColor="#377DFF0D" /></u-form-item>  
22 - </u-form>  
23 - <!-- <qiun-data-charts type="tarea" :chartData="chartData" canvas2d /> -->  
24 - </view>  
25 - <view class="historyData-bottom">  
26 - <view class="table">  
27 - <view class="tr bg-w">  
28 - <view class="th">变量值</view>  
29 - <view class="th">更新时间</view>  
30 - </view>  
31 - <view class="tr bg-g">  
32 - <view class="td">10</view>  
33 - <view class="td">2022-03-01 18:16:33</view>  
34 - </view>  
35 -  
36 - </view>  
37 - </view>  
38 - <u-calendar  
39 - :show="showCalendar"  
40 - closeOnClickOverlay  
41 - mode="range"  
42 - startText="开始时间"  
43 - endText="结束时间"  
44 - confirmDisabledText="请选择日期"  
45 - @confirm="calendarConfirm"  
46 - @close="calendarClose"  
47 - ></u-calendar>  
48 - <u-picker :show="showTimeGap" :columns="columns" keyName="label" closeOnClickOverlay @confirm="confirmTimeGap" @cancel="cancelTimeGap" @close="cancelTimeGap"></u-picker>  
49 - <u-picker :show="showSelectType" :columns="keys" closeOnClickOverlay @confirm="confirmTypeGap" @cancel="cancelTypeGap" @close="cancelTypeGap"></u-picker>  
50 - <f-tabbar></f-tabbar>  
51 - </view>  
52 -</template>  
53 -  
54 -<script>  
55 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
56 -import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue';  
57 -import { getDeviceKeys, getHistroyData } from '../api/index.js';  
58 -export default {  
59 - components: {  
60 - fTabbar,  
61 - qiunDataCharts  
62 - },  
63 - props:{  
64 - keys:{  
65 - type:Array,  
66 - default:()=>[]  
67 - }  
68 - },  
69 - data() {  
70 - return {  
71 - showCalendar: false,  
72 - showTimeGap: false,  
73 - showSelectType: false,  
74 - columns: [  
75 - [  
76 - {  
77 - label: '5分钟',  
78 - value: 300  
79 - },  
80 - {  
81 - label: '10分钟',  
82 - value: 600  
83 - },  
84 - {  
85 - label: '15分钟',  
86 - value: 900  
87 - },  
88 - {  
89 - label: '30分钟',  
90 - value: 1800  
91 - },  
92 - {  
93 - label: '1小时',  
94 - value: 3600  
95 - },  
96 - {  
97 - label: '2小时',  
98 - value: 7200  
99 - },  
100 - {  
101 - label: '6小时',  
102 - value: 21600  
103 - }  
104 - ]  
105 - ],  
106 - timeData: {  
107 - selectTime: '',  
108 - getTimeGap: '',  
109 - getType: ''  
110 - }  
111 - };  
112 - },  
113 - methods: {  
114 - openCalendar() {  
115 - this.showCalendar = true;  
116 - },  
117 - openTimeGap() {  
118 - this.showTimeGap = true;  
119 - },  
120 - openType() {  
121 - this.showSelectType = true;  
122 - },  
123 - calendarConfirm(date) {  
124 - this.showCalendar = false;  
125 - this.timeData.selectTime = `${date[0]} 至 ${date[1]}`;  
126 - },  
127 - calendarClose() {  
128 - this.showCalendar = false;  
129 - },  
130 - confirmTimeGap(time) {  
131 - this.showTimeGap = false;  
132 - this.timeData.getTimeGap = time.value[0].label;  
133 - },  
134 -  
135 - cancelTimeGap() {  
136 - this.showTimeGap = false;  
137 - },  
138 - confirmTypeGap(time) {  
139 - this.showSelectType = false;  
140 - this.timeData.getType = time.value[0];  
141 - },  
142 - cancelTypeGap() {  
143 - this.showSelectType = false;  
144 - }  
145 - }  
146 -};  
147 -</script>  
148 -  
149 -<style lang="scss" scoped>  
150 -.historyData {  
151 - margin: 30rpx;  
152 - .historyData-top {  
153 - padding: 30rpx;  
154 - background-color: #fff;  
155 - height: 870rpx;  
156 - border-radius: 20rpx;  
157 - .icon {  
158 - width: 28rpx;  
159 - height: 28rpx;  
160 - margin-right: 15rpx;  
161 - }  
162 - }  
163 - .historyData-bottom {  
164 - margin-top: 30rpx;  
165 - background-color: #fff;  
166 - border-radius: 20rpx;  
167 - .table {  
168 - border: 0px solid darkgray;  
169 - .tr {  
170 - display: flex;  
171 - width: 100%;  
172 - justify-content: center;  
173 - height: 3rem;  
174 - align-items: center;  
175 - .th {  
176 - display: flex;  
177 - justify-content: center;  
178 - align-items: center;  
179 - width: 50%;  
180 - color: #333;  
181 - font-weight: 500;  
182 - }  
183 - .td {  
184 - color: #999;  
185 - width: 50%;  
186 - display: flex;  
187 - justify-content: center;  
188 - text-align: center;  
189 - }  
190 - }  
191 - }  
192 - }  
193 -}  
194 -.odd {  
195 - background-color: #f9fcff;  
196 -} 1 +<template>
  2 + <view class="historyData">
  3 + <!-- 公共组件-每个页面必须引入 -->
  4 + <public-module></public-module>
  5 + <view class="historyData-top">
  6 + <u-form :label-style="{ 'font-size': '0rpx' }">
  7 + <u-form-item @click="openCalendar">
  8 + <u-input v-model="timeData.selectTime" disabled disabledColor="#fff" placeholder="请选择日期" border="none">
  9 + <template slot="prefix">
  10 + <image class="icon" src="../../../static/can-der.png"></image>
  11 + </template>
  12 + </u-input>
  13 + </u-form-item>
  14 + <u-form-item @click="openTimeGap">
  15 + <u-input v-model="timeData.getTimeGap" disabled disabledColor="#fff" placeholder="请选择时间区间" border="none">
  16 + <template slot="prefix">
  17 + <image class="icon" src="../../../static/time.png"></image>
  18 + </template>
  19 + </u-input>
  20 + </u-form-item>
  21 + <u-form-item @click="openType"><u-input shape="circle" v-model="timeData.getType" placeholder="请选择属性" disabled disabledColor="#377DFF0D" /></u-form-item>
  22 + </u-form>
  23 + <!-- <qiun-data-charts type="tarea" :chartData="chartData" canvas2d /> -->
  24 + </view>
  25 + <view class="historyData-bottom">
  26 + <view class="table">
  27 + <view class="tr bg-w">
  28 + <view class="th">变量值</view>
  29 + <view class="th">更新时间</view>
  30 + </view>
  31 + <view class="tr bg-g">
  32 + <view class="td">10</view>
  33 + <view class="td">2022-03-01 18:16:33</view>
  34 + </view>
  35 +
  36 + </view>
  37 + </view>
  38 + <u-calendar
  39 + :show="showCalendar"
  40 + closeOnClickOverlay
  41 + mode="range"
  42 + startText="开始时间"
  43 + endText="结束时间"
  44 + confirmDisabledText="请选择日期"
  45 + @confirm="calendarConfirm"
  46 + @close="calendarClose"
  47 + ></u-calendar>
  48 + <u-picker :show="showTimeGap" :columns="columns" keyName="label" closeOnClickOverlay @confirm="confirmTimeGap" @cancel="cancelTimeGap" @close="cancelTimeGap"></u-picker>
  49 + <u-picker :show="showSelectType" :columns="keys" closeOnClickOverlay @confirm="confirmTypeGap" @cancel="cancelTypeGap" @close="cancelTypeGap"></u-picker>
  50 + <f-tabbar></f-tabbar>
  51 + </view>
  52 +</template>
  53 +
  54 +<script>
  55 +import fTabbar from '@/components/module/f-tabbar/f-tabbar';
  56 +import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue';
  57 +import { getDeviceKeys, getHistroyData } from '../../../pages/device/api/index';
  58 +export default {
  59 + components: {
  60 + fTabbar,
  61 + qiunDataCharts
  62 + },
  63 + props:{
  64 + keys:{
  65 + type:Array,
  66 + default:()=>[]
  67 + }
  68 + },
  69 + data() {
  70 + return {
  71 + showCalendar: false,
  72 + showTimeGap: false,
  73 + showSelectType: false,
  74 + columns: [
  75 + [
  76 + {
  77 + label: '5分钟',
  78 + value: 300
  79 + },
  80 + {
  81 + label: '10分钟',
  82 + value: 600
  83 + },
  84 + {
  85 + label: '15分钟',
  86 + value: 900
  87 + },
  88 + {
  89 + label: '30分钟',
  90 + value: 1800
  91 + },
  92 + {
  93 + label: '1小时',
  94 + value: 3600
  95 + },
  96 + {
  97 + label: '2小时',
  98 + value: 7200
  99 + },
  100 + {
  101 + label: '6小时',
  102 + value: 21600
  103 + }
  104 + ]
  105 + ],
  106 + timeData: {
  107 + selectTime: '',
  108 + getTimeGap: '',
  109 + getType: ''
  110 + }
  111 + };
  112 + },
  113 + methods: {
  114 + openCalendar() {
  115 + this.showCalendar = true;
  116 + },
  117 + openTimeGap() {
  118 + this.showTimeGap = true;
  119 + },
  120 + openType() {
  121 + this.showSelectType = true;
  122 + },
  123 + calendarConfirm(date) {
  124 + this.showCalendar = false;
  125 + this.timeData.selectTime = `${date[0]} 至 ${date[1]}`;
  126 + },
  127 + calendarClose() {
  128 + this.showCalendar = false;
  129 + },
  130 + confirmTimeGap(time) {
  131 + this.showTimeGap = false;
  132 + this.timeData.getTimeGap = time.value[0].label;
  133 + },
  134 +
  135 + cancelTimeGap() {
  136 + this.showTimeGap = false;
  137 + },
  138 + confirmTypeGap(time) {
  139 + this.showSelectType = false;
  140 + this.timeData.getType = time.value[0];
  141 + },
  142 + cancelTypeGap() {
  143 + this.showSelectType = false;
  144 + }
  145 + }
  146 +};
  147 +</script>
  148 +
  149 +<style lang="scss" scoped>
  150 +.historyData {
  151 + margin: 30rpx;
  152 + .historyData-top {
  153 + padding: 30rpx;
  154 + background-color: #fff;
  155 + height: 870rpx;
  156 + border-radius: 20rpx;
  157 + .icon {
  158 + width: 28rpx;
  159 + height: 28rpx;
  160 + margin-right: 15rpx;
  161 + }
  162 + }
  163 + .historyData-bottom {
  164 + margin-top: 30rpx;
  165 + background-color: #fff;
  166 + border-radius: 20rpx;
  167 + .table {
  168 + border: 0px solid darkgray;
  169 + .tr {
  170 + display: flex;
  171 + width: 100%;
  172 + justify-content: center;
  173 + height: 3rem;
  174 + align-items: center;
  175 + .th {
  176 + display: flex;
  177 + justify-content: center;
  178 + align-items: center;
  179 + width: 50%;
  180 + color: #333;
  181 + font-weight: 500;
  182 + }
  183 + .td {
  184 + color: #999;
  185 + width: 50%;
  186 + display: flex;
  187 + justify-content: center;
  188 + text-align: center;
  189 + }
  190 + }
  191 + }
  192 + }
  193 +}
  194 +.odd {
  195 + background-color: #f9fcff;
  196 +}
197 </style> 197 </style>
deviceSubPage/deviceDetailPage/tabDetail/realtimeData.vue renamed from pages/device/tabDetail/realtimeData.vue
feedBackSubPage/feedback/feedback.vue renamed from pages/feedback/feedback.vue
@@ -26,21 +26,6 @@ Vue.use(f_show_modal) @@ -26,21 +26,6 @@ Vue.use(f_show_modal)
26 import uView from '@/uni_modules/uview-ui' 26 import uView from '@/uni_modules/uview-ui'
27 Vue.use(uView) 27 Vue.use(uView)
28 28
29 -// #ifdef MP  
30 -// 引入uView对小程序分享的mixin封装  
31 -const mpShare = require('@/uni_modules/uview-ui/libs/mixin/mpShare.js')  
32 -Vue.mixin(mpShare)  
33 -// #endif  
34 -  
35 -// #ifdef H5  
36 -//微信公众号(分享、扫码、获取位置等)  
37 -import '@/plugins/jwxUtils.js';  
38 -// #endif  
39 -  
40 -// 基于iconfont图标库组件  
41 -// import fIcon from "@/components/module/f-icon/f-icon.vue";  
42 -// Vue.component("f-icon", fIcon);  
43 -  
44 // 公共组件 29 // 公共组件
45 import publicModule from "@/components/common/public-module.vue"; 30 import publicModule from "@/components/common/public-module.vue";
46 Vue.component("public-module", publicModule); 31 Vue.component("public-module", publicModule);
1 { 1 {
2 - "name": "yun-teng-app",  
3 - "appid": "__UNI__C873643",  
4 - "description": "云腾app、小程序",  
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 - "distribute": {  
20 - "android": {  
21 - "permissions": [  
22 - "<uses-feature android:name=\"android.hardware.camera\"/>",  
23 - "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",  
24 - "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",  
25 - "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",  
26 - "<uses-permission android:name=\"android.permission.CAMERA\"/>",  
27 - "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",  
28 - "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",  
29 - "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",  
30 - "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",  
31 - "<uses-permission android:name=\"android.permission.INSTALL_PACKAGES\"/>",  
32 - "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",  
33 - "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",  
34 - "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",  
35 - "<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\"/>",  
36 - "<uses-permission android:name=\"android.permission.VIBRATE\"/>",  
37 - "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",  
38 - "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"  
39 - ]  
40 - },  
41 - "ios": {},  
42 - "sdkConfigs": {  
43 - "ad": {},  
44 - "geolocation": {  
45 - "system": {  
46 - "__platform__": ["ios", "android"]  
47 - },  
48 - "amap": {  
49 - "__platform__": ["ios", "android"],  
50 - "appkey_ios": "",  
51 - "appkey_android": ""  
52 - }  
53 - },  
54 - "maps": {}  
55 - }  
56 - }  
57 - },  
58 - "quickapp": {},  
59 - "mp-weixin": {  
60 - "appid": "wx0ad61d7bf6808e02",  
61 - "setting": {  
62 - "urlCheck": false,  
63 - "minified": true,  
64 - "es6": true  
65 - },  
66 - "usingComponents": true,  
67 - "permission": {  
68 - "scope.userLocation": {  
69 - "desc": "你的位置信息将用于小程序位置接口的效果展示"  
70 - }  
71 - },  
72 - "lazyCodeLoading": "requiredComponents"  
73 - },  
74 - "mp-alipay": {  
75 - "usingComponents": true  
76 - },  
77 - "mp-baidu": {  
78 - "usingComponents": true  
79 - },  
80 - "mp-toutiao": {  
81 - "usingComponents": true  
82 - },  
83 - "uniStatistics": {  
84 - "enable": false  
85 - },  
86 - "vueVersion": "2",  
87 - "h5": {  
88 - "sdkConfigs": {  
89 - "maps": {}  
90 - },  
91 - "router": {  
92 - "base": "minImage/h5/"  
93 - }  
94 - } 2 + "name" : "yun-teng-app",
  3 + "appid" : "__UNI__C873643",
  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 + "distribute" : {
  20 + "android" : {
  21 + "permissions" : [
  22 + "<uses-feature android:name=\"android.hardware.camera\"/>",
  23 + "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
  24 + "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
  25 + "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
  26 + "<uses-permission android:name=\"android.permission.CAMERA\"/>",
  27 + "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
  28 + "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
  29 + "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
  30 + "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
  31 + "<uses-permission android:name=\"android.permission.INSTALL_PACKAGES\"/>",
  32 + "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
  33 + "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
  34 + "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
  35 + "<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\"/>",
  36 + "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
  37 + "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
  38 + "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
  39 + ]
  40 + },
  41 + "ios" : {},
  42 + "sdkConfigs" : {
  43 + "ad" : {},
  44 + "geolocation" : {
  45 + "system" : {
  46 + "__platform__" : [ "ios", "android" ]
  47 + },
  48 + "amap" : {
  49 + "__platform__" : [ "ios", "android" ],
  50 + "appkey_ios" : "",
  51 + "appkey_android" : ""
  52 + }
  53 + },
  54 + "maps" : {}
  55 + }
  56 + }
  57 + },
  58 + "quickapp" : {},
  59 + "mp-weixin" : {
  60 + "appid" : "wxd5d018355f38262b",
  61 + "setting" : {
  62 + "urlCheck" : false,
  63 + "minified" : true,
  64 + "es6" : true,
  65 + "postcss" : true
  66 + },
  67 + "usingComponents" : true,
  68 + "permission" : {
  69 + "scope.userLocation" : {
  70 + "desc" : "你的位置信息将用于小程序位置接口的效果展示"
  71 + }
  72 + },
  73 + "lazyCodeLoading" : "requiredComponents",
  74 + //开启分包优化
  75 + "optimization" : {
  76 + "subPackages" : true
  77 + }
  78 + },
  79 + "mp-alipay" : {
  80 + "usingComponents" : true
  81 + },
  82 + "mp-baidu" : {
  83 + "usingComponents" : true
  84 + },
  85 + "mp-toutiao" : {
  86 + "usingComponents" : true
  87 + },
  88 + "uniStatistics" : {
  89 + "enable" : false
  90 + },
  91 + "vueVersion" : "2",
  92 + "h5" : {
  93 + "sdkConfigs" : {
  94 + "maps" : {}
  95 + },
  96 + "router" : {
  97 + "base" : "minImage/h5/"
  98 + }
  99 + }
95 } 100 }
@@ -4,7 +4,8 @@ @@ -4,7 +4,8 @@
4 "description": "### 项目结构", 4 "description": "### 项目结构",
5 "main": "main.js", 5 "main": "main.js",
6 "scripts": { 6 "scripts": {
7 - "test": "echo \"Error: no test specified\" && exit 1" 7 + "test": "echo \"Error: no test specified\" && exit 1",
  8 + "dev:mp-wenxin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize"
8 }, 9 },
9 "repository": { 10 "repository": {
10 "type": "git", 11 "type": "git",
@@ -14,12 +14,12 @@ @@ -14,12 +14,12 @@
14 "navigationBarTitleText": "设备" 14 "navigationBarTitleText": "设备"
15 } 15 }
16 }, 16 },
17 - {  
18 - "path": "pages/device/deviceDetail",  
19 - "style": {  
20 - "navigationBarTitleText": "设备详情"  
21 - }  
22 - }, 17 + // {
  18 + // "path": "pages/device/deviceDetail",
  19 + // "style": {
  20 + // "navigationBarTitleText": "设备详情"
  21 + // }
  22 + // },
23 { 23 {
24 "path": "pages/device/org/org", 24 "path": "pages/device/org/org",
25 "style": { 25 "style": {
@@ -33,9 +33,9 @@ @@ -33,9 +33,9 @@
33 } 33 }
34 }, 34 },
35 { 35 {
36 - "path": "pages/alarm/alarmDetail", 36 + "path": "pages/alarm/org/org",
37 "style": { 37 "style": {
38 - "navigationBarTitleText": "告警详情" 38 + "navigationBarTitleText": "组织筛选"
39 } 39 }
40 }, 40 },
41 { 41 {
@@ -43,44 +43,8 @@ @@ -43,44 +43,8 @@
43 "style": { 43 "style": {
44 "navigationBarTitleText": "个人中心" 44 "navigationBarTitleText": "个人中心"
45 } 45 }
46 - }, {  
47 - "path": "pages/personal/code",  
48 - "style": {  
49 - "navigationBarTitleText": "验证码登录"  
50 - }  
51 -  
52 - }, {  
53 - "path": "pages/personal/findPassword",  
54 - "style": {  
55 - "navigationBarTitleText": "找回密码"  
56 - }  
57 -  
58 - }, {  
59 - "path": "pages/personal/set",  
60 - "style": {  
61 - "navigationBarTitleText": "个人资料"  
62 - }  
63 -  
64 - }, {  
65 - "path": "pages/systemNotify/systemNotify",  
66 - "style": {  
67 - "navigationBarTitleText": "通知列表"  
68 - }  
69 }, 46 },
70 { 47 {
71 - "path": "pages/systemNotify/notifyDetail",  
72 - "style": {  
73 - "navigationBarTitleText": "通知详情"  
74 - }  
75 - }, {  
76 - "path": "pages/feedback/feedback",  
77 - "style": {  
78 - "navigationBarTitleText": "意见反馈",  
79 - "app-plus": {  
80 - "scrollIndicator": "none"  
81 - }  
82 - }  
83 - }, {  
84 "path": "pages/index/camera/camera", 48 "path": "pages/index/camera/camera",
85 "style": { 49 "style": {
86 "navigationBarTitleText": "查看摄像头" 50 "navigationBarTitleText": "查看摄像头"
@@ -98,33 +62,86 @@ @@ -98,33 +62,86 @@
98 } 62 }
99 63
100 }, 64 },
101 -  
102 { 65 {
103 "path": "pages/index/configuration/configurationDetail", 66 "path": "pages/index/configuration/configurationDetail",
104 "style": { 67 "style": {
105 "navigationBarTitleText": "组态详情" 68 "navigationBarTitleText": "组态详情"
106 } 69 }
107 - 70 + }
  71 + ],
  72 + "subPackages": [{
  73 + "root": "alarmSubPage",
  74 + "pages": [{
  75 + "path": "alarmDetailPage/alarmDetail",
  76 + "style": {
  77 + "navigationBarTitleText": "告警详情"
  78 + }
  79 + }]
108 }, 80 },
109 { 81 {
110 - "path": "pages/alarm/org/org",  
111 - "style": {  
112 - "navigationBarTitleText": "组织筛选"  
113 - }  
114 - 82 + "root": "deviceSubPage",
  83 + "pages": [{
  84 + "path": "deviceDetailPage/deviceDetail",
  85 + "style": {
  86 + "navigationBarTitleText": "设备详情"
  87 + }
  88 + }]
115 }, 89 },
116 { 90 {
117 - "path": "pages/public/login",  
118 - "style": {  
119 - "navigationBarTitleText": "登录"  
120 - }  
121 - 91 + "root": "sysNotifySubPage",
  92 + "pages": [{
  93 + "path": "sysNotifyPage/systemNotify",
  94 + "style": {
  95 + "navigationBarTitleText": "系统通知"
  96 + }
  97 + },
  98 + {
  99 + "path": "sysNotifyPage/notifyDetail",
  100 + "style": {
  101 + "navigationBarTitleText": "通知详情"
  102 + }
  103 + }
  104 + ]
  105 + },
  106 + {
  107 + "root": "feedBackSubPage",
  108 + "pages": [{
  109 + "path": "feedback/feedback",
  110 + "style": {
  111 + "navigationBarTitleText": "意见反馈"
  112 + }
  113 + }]
  114 + },
  115 + {
  116 + "root": "publicLoginSubPage",
  117 + "pages": [{
  118 + "path": "public/login",
  119 + "style": {
  120 + "navigationBarTitleText": "登录"
  121 + }
  122 + },
  123 + {
  124 + "path": "other/set",
  125 + "style": {
  126 + "navigationBarTitleText": "个人资料"
  127 + }
  128 + },
  129 + {
  130 + "path": "other/code",
  131 + "style": {
  132 + "navigationBarTitleText": "验证码登录"
  133 + }
  134 + },
  135 + {
  136 + "path": "other/findPassword",
  137 + "style": {
  138 + "navigationBarTitleText": "忘记密码"
  139 + }
  140 + }
  141 + ]
122 } 142 }
123 ], 143 ],
124 "globalStyle": { 144 "globalStyle": {
125 - "mp-alipay": {  
126 - "allowsBounceVertical": "NO"  
127 - },  
128 "navigationBarTextStyle": "black", 145 "navigationBarTextStyle": "black",
129 "navigationBarTitleText": "云腾app", 146 "navigationBarTitleText": "云腾app",
130 "navigationBarBackgroundColor": "#FFFFFF", 147 "navigationBarBackgroundColor": "#FFFFFF",
@@ -427,7 +427,8 @@ export default { @@ -427,7 +427,8 @@ export default {
427 status: e.status 427 status: e.status
428 }; 428 };
429 uni.navigateTo({ 429 uni.navigateTo({
430 - url: './alarmDetail?data=' + JSON.stringify(obj) 430 + url:'/alarmSubPage/alarmDetailPage/alarmDetail?data='+JSON.stringify(obj)
  431 + // url: '/' + JSON.stringify(obj)
431 }); 432 });
432 } 433 }
433 } 434 }
@@ -225,7 +225,7 @@ export default { @@ -225,7 +225,7 @@ export default {
225 }, 225 },
226 openDeviceDetail(id, alarmStatus, lastOnlineTime,tbDeviceId) { 226 openDeviceDetail(id, alarmStatus, lastOnlineTime,tbDeviceId) {
227 uni.navigateTo({ 227 uni.navigateTo({
228 - url: `deviceDetail?id=${id}&alarmStatus=${alarmStatus}&lastOnlineTime=${lastOnlineTime}&tbDeviceId=${tbDeviceId}` 228 + url: `/deviceSubPage/deviceDetailPage/deviceDetail?id=${id}&alarmStatus=${alarmStatus}&lastOnlineTime=${lastOnlineTime}&tbDeviceId=${tbDeviceId}`
229 }); 229 });
230 }, 230 },
231 handleClickTag(currentIndex, list) { 231 handleClickTag(currentIndex, list) {
@@ -296,4 +296,4 @@ export default { @@ -296,4 +296,4 @@ export default {
296 } 296 }
297 } 297 }
298 } 298 }
299 -</style> 299 +</style>
@@ -102,7 +102,7 @@ export default { @@ -102,7 +102,7 @@ export default {
102 uni.$u.http.get('/yt/video', { params: httpData, custom: { load: false } }).then(res => { 102 uni.$u.http.get('/yt/video', { params: httpData, custom: { load: false } }).then(res => {
103 if (res) { 103 if (res) {
104 console.log('Video', res); 104 console.log('Video', res);
105 - // this.list = res.items; 105 + this.list = res.items;
106 } 106 }
107 }); 107 });
108 }, 108 },
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 <!-- 登录 --> 7 <!-- 登录 -->
8 <view class="u-flex u-p-l-30 u-p-r-20 u-p-t-75 u-p-b-30"> 8 <view class="u-flex u-p-l-30 u-p-r-20 u-p-t-75 u-p-b-30">
9 <block v-if="userInfo.isToken"> 9 <block v-if="userInfo.isToken">
10 - <view @click="openPersonalInfo" class="u-m-r-20"><image class="avatar" mode="aspectFill" :src="userInfo.avatar || '../../static/default-avatar.png'"></image></view> 10 + <view @click="openPersonalInfo" class="u-m-r-20"><image class="avatar" mode="aspectFill" :src="userInfo.avatar"></image></view>
11 <view @click="openPersonalInfo" class="u-flex-1"> 11 <view @click="openPersonalInfo" class="u-flex-1">
12 <view class="nickName u-flex"> 12 <view class="nickName u-flex">
13 <view class="name u-m-r-10" v-if="userInfo.realName"> 13 <view class="name u-m-r-10" v-if="userInfo.realName">
@@ -34,7 +34,7 @@ @@ -34,7 +34,7 @@
34 <!-- 登录 --> 34 <!-- 登录 -->
35 <view class="u-flex u-p-l-30 u-p-r-20 u-p-t-75 u-p-b-30"> 35 <view class="u-flex u-p-l-30 u-p-r-20 u-p-t-75 u-p-b-30">
36 <block v-if="userInfo.isToken"> 36 <block v-if="userInfo.isToken">
37 - <view @click="openPersonalInfo" class="u-m-r-20"><image class="avatar" mode="aspectFill" :src="userInfo.avatar||'../../static/default-avatar.png'"></image></view> 37 + <view @click="openPersonalInfo" class="u-m-r-20"><image class="avatar" mode="aspectFill" :src="userInfo.avatar"></image></view>
38 <view @click="openPersonalInfo" class="u-flex-1"> 38 <view @click="openPersonalInfo" class="u-flex-1">
39 <view class="nickName u-flex"> 39 <view class="nickName u-flex">
40 <view class="name u-m-r-10" v-if="userInfo.realName"> 40 <view class="name u-m-r-10" v-if="userInfo.realName">
@@ -60,12 +60,12 @@ @@ -60,12 +60,12 @@
60 </view> 60 </view>
61 <view class="u-flex my-nav"> 61 <view class="u-flex my-nav">
62 <view class="nav-main"> 62 <view class="nav-main">
63 - <view @click="onTokenJump('../systemNotify/systemNotify')" class="u-flex nav-link"> 63 + <view @click="onTokenJump('/sysNotifySubPage/sysNotifyPage/systemNotify')" class="u-flex nav-link">
64 <view class="nav-image"><image class="image" src="../../static/sys-not.png"></image></view> 64 <view class="nav-image"><image class="image" src="../../static/sys-not.png"></image></view>
65 <view class="nav-center"><text class="text">系统通知</text></view> 65 <view class="nav-center"><text class="text">系统通知</text></view>
66 <view class="nav-right"><image class="image" src="../../static/arrow-right.png"></image></view> 66 <view class="nav-right"><image class="image" src="../../static/arrow-right.png"></image></view>
67 </view> 67 </view>
68 - <view @click="onTokenJump('../feedback/feedback')" class="u-flex nav-link"> 68 + <view @click="onTokenJump('/feedBackSubPage/feedback/feedback')" class="u-flex nav-link">
69 <view class="nav-image"><image class="image" src="../../static/find-sugg.png"></image></view> 69 <view class="nav-image"><image class="image" src="../../static/find-sugg.png"></image></view>
70 <view class="nav-center"><text class="text">意见反馈</text></view> 70 <view class="nav-center"><text class="text">意见反馈</text></view>
71 <view class="nav-right"><image class="image" src="../../static/arrow-right.png"></image></view> 71 <view class="nav-right"><image class="image" src="../../static/arrow-right.png"></image></view>
@@ -173,18 +173,6 @@ export default { @@ -173,18 +173,6 @@ export default {
173 title: '绑定账号', 173 title: '绑定账号',
174 systemInfo: base.systemInfo, 174 systemInfo: base.systemInfo,
175 PrimaryButtonColor: '#0079fe', //主题色 175 PrimaryButtonColor: '#0079fe', //主题色
176 - list: [  
177 - {  
178 - title: '系统通知',  
179 - url: '../systemNotify/systemNotify',  
180 - icon: 'setting-fill'  
181 - },  
182 - {  
183 - title: '意见反馈',  
184 - url: '../feedback/feedback',  
185 - icon: 'more-circle-fill'  
186 - }  
187 - ]  
188 }; 176 };
189 }, 177 },
190 onLoad() { 178 onLoad() {
@@ -204,16 +192,6 @@ export default { @@ -204,16 +192,6 @@ export default {
204 }); 192 });
205 }); 193 });
206 }, 194 },
207 - // openSysNotify() {  
208 - // uni.navigateTo({  
209 - // url: '../systemNotify/systemNotify'  
210 - // });  
211 - // },  
212 - // openFeedBack() {  
213 - // uni.navigateTo({  
214 - // url: '../feedback/feedback'  
215 - // });  
216 - // },  
217 onJump(url) { 195 onJump(url) {
218 uni.navigateTo({ 196 uni.navigateTo({
219 url: url 197 url: url
@@ -221,7 +199,7 @@ export default { @@ -221,7 +199,7 @@ export default {
221 }, 199 },
222 openLoginFunc() { 200 openLoginFunc() {
223 uni.navigateTo({ 201 uni.navigateTo({
224 - url: '../public/login' 202 + url: '/publicLoginSubPage/public/login'
225 }); 203 });
226 }, 204 },
227 openPersonalInfo() { 205 openPersonalInfo() {
@@ -229,7 +207,7 @@ export default { @@ -229,7 +207,7 @@ export default {
229 data: this.userInfo 207 data: this.userInfo
230 }; 208 };
231 uni.navigateTo({ 209 uni.navigateTo({
232 - url: './set?data=' + JSON.stringify(obj) 210 + url: '/publicLoginSubPage/other/set?data=' + JSON.stringify(obj)
233 }); 211 });
234 }, 212 },
235 clickAccountFunc() { 213 clickAccountFunc() {
@@ -306,7 +284,7 @@ export default { @@ -306,7 +284,7 @@ export default {
306 that.showLogout = false; 284 that.showLogout = false;
307 setTimeout(() => { 285 setTimeout(() => {
308 uni.navigateTo({ 286 uni.navigateTo({
309 - url: '../public/login' 287 + url: '/publicLoginSubPage/public/login'
310 }); 288 });
311 }, 500); 289 }, 500);
312 } else if (res.cancel) { 290 } else if (res.cancel) {
1 -!function(e,n){"function"==typeof define&&(define.amd||define.cmd)?define(function(){return n(e)}):n(e,!0)}(this,function(e,n){function i(n,i,t){e.WeixinJSBridge?WeixinJSBridge.invoke(n,o(i),function(e){c(n,e,t)}):u(n,t)}function t(n,i,t){e.WeixinJSBridge?WeixinJSBridge.on(n,function(e){t&&t.trigger&&t.trigger(e),c(n,e,i)}):t?u(n,t):u(n,i)}function o(e){return e=e||{},e.appId=C.appId,e.verifyAppId=C.appId,e.verifySignType="sha1",e.verifyTimestamp=C.timestamp+"",e.verifyNonceStr=C.nonceStr,e.verifySignature=C.signature,e}function r(e){return{timeStamp:e.timestamp+"",nonceStr:e.nonceStr,package:e.package,paySign:e.paySign,signType:e.signType||"SHA1"}}function a(e){return e.postalCode=e.addressPostalCode,delete e.addressPostalCode,e.provinceName=e.proviceFirstStageName,delete e.proviceFirstStageName,e.cityName=e.addressCitySecondStageName,delete e.addressCitySecondStageName,e.countryName=e.addressCountiesThirdStageName,delete e.addressCountiesThirdStageName,e.detailInfo=e.addressDetailInfo,delete e.addressDetailInfo,e}function c(e,n,i){"openEnterpriseChat"==e&&(n.errCode=n.err_code),delete n.err_code,delete n.err_desc,delete n.err_detail;var t=n.errMsg;t||(t=n.err_msg,delete n.err_msg,t=s(e,t),n.errMsg=t),(i=i||{})._complete&&(i._complete(n),delete i._complete),t=n.errMsg||"",C.debug&&!i.isInnerInvoke&&alert(JSON.stringify(n));var o=t.indexOf(":");switch(t.substring(o+1)){case"ok":i.success&&i.success(n);break;case"cancel":i.cancel&&i.cancel(n);break;default:i.fail&&i.fail(n)}i.complete&&i.complete(n)}function s(e,n){var i=e,t=v[i];t&&(i=t);var o="ok";if(n){var r=n.indexOf(":");"confirm"==(o=n.substring(r+1))&&(o="ok"),"failed"==o&&(o="fail"),-1!=o.indexOf("failed_")&&(o=o.substring(7)),-1!=o.indexOf("fail_")&&(o=o.substring(5)),"access denied"!=(o=(o=o.replace(/_/g," ")).toLowerCase())&&"no permission to execute"!=o||(o="permission denied"),"config"==i&&"function not exist"==o&&(o="ok"),""==o&&(o="fail")}return n=i+":"+o}function d(e){if(e){for(var n=0,i=e.length;n<i;++n){var t=e[n],o=h[t];o&&(e[n]=o)}return e}}function u(e,n){if(!(!C.debug||n&&n.isInnerInvoke)){var i=v[e];i&&(e=i),n&&n._complete&&delete n._complete,console.log('"'+e+'",',n||"")}}function l(e){if(!(k||w||C.debug||x<"6.0.2"||V.systemType<0)){var n=new Image;V.appId=C.appId,V.initTime=A.initEndTime-A.initStartTime,V.preVerifyTime=A.preVerifyEndTime-A.preVerifyStartTime,N.getNetworkType({isInnerInvoke:!0,success:function(e){V.networkType=e.networkType;var i="https://open.weixin.qq.com/sdk/report?v="+V.version+"&o="+V.isPreVerifyOk+"&s="+V.systemType+"&c="+V.clientVersion+"&a="+V.appId+"&n="+V.networkType+"&i="+V.initTime+"&p="+V.preVerifyTime+"&u="+V.url;n.src=i}})}}function p(){return(new Date).getTime()}function f(n){T&&(e.WeixinJSBridge?n():S.addEventListener&&S.addEventListener("WeixinJSBridgeReady",n,!1))}function m(){N.invoke||(N.invoke=function(n,i,t){e.WeixinJSBridge&&WeixinJSBridge.invoke(n,o(i),t)},N.on=function(n,i){e.WeixinJSBridge&&WeixinJSBridge.on(n,i)})}function g(e){if("string"==typeof e&&e.length>0){var n=e.split("?")[0],i=e.split("?")[1];return n+=".html",void 0!==i?n+"?"+i:n}}if(!e.jWeixin){var h={config:"preVerifyJSAPI",onMenuShareTimeline:"menu:share:timeline",onMenuShareAppMessage:"menu:share:appmessage",onMenuShareQQ:"menu:share:qq",onMenuShareWeibo:"menu:share:weiboApp",onMenuShareQZone:"menu:share:QZone",previewImage:"imagePreview",getLocation:"geoLocation",openProductSpecificView:"openProductViewWithPid",addCard:"batchAddCard",openCard:"batchViewCard",chooseWXPay:"getBrandWCPayRequest",openEnterpriseRedPacket:"getRecevieBizHongBaoRequest",startSearchBeacons:"startMonitoringBeacons",stopSearchBeacons:"stopMonitoringBeacons",onSearchBeacons:"onBeaconsInRange",consumeAndShareCard:"consumedShareCard",openAddress:"editAddress"},v=function(){var e={};for(var n in h)e[h[n]]=n;return e}(),S=e.document,I=S.title,y=navigator.userAgent.toLowerCase(),_=navigator.platform.toLowerCase(),k=!(!_.match("mac")&&!_.match("win")),w=-1!=y.indexOf("wxdebugger"),T=-1!=y.indexOf("micromessenger"),M=-1!=y.indexOf("android"),P=-1!=y.indexOf("iphone")||-1!=y.indexOf("ipad"),x=function(){var e=y.match(/micromessenger\/(\d+\.\d+\.\d+)/)||y.match(/micromessenger\/(\d+\.\d+)/);return e?e[1]:""}(),A={initStartTime:p(),initEndTime:0,preVerifyStartTime:0,preVerifyEndTime:0},V={version:1,appId:"",initTime:0,preVerifyTime:0,networkType:"",isPreVerifyOk:1,systemType:P?1:M?2:-1,clientVersion:x,url:encodeURIComponent(location.href)},C={},L={_completes:[]},B={state:0,data:{}};f(function(){A.initEndTime=p()});var O=!1,E=[],N={config:function(e){C=e,u("config",e);var n=!1!==C.check;f(function(){if(n)i(h.config,{verifyJsApiList:d(C.jsApiList)},function(){L._complete=function(e){A.preVerifyEndTime=p(),B.state=1,B.data=e},L.success=function(e){V.isPreVerifyOk=0},L.fail=function(e){L._fail?L._fail(e):B.state=-1};var e=L._completes;return e.push(function(){l()}),L.complete=function(n){for(var i=0,t=e.length;i<t;++i)e[i]();L._completes=[]},L}()),A.preVerifyStartTime=p();else{B.state=1;for(var e=L._completes,t=0,o=e.length;t<o;++t)e[t]();L._completes=[]}}),m()},ready:function(e){0!=B.state?e():(L._completes.push(e),!T&&C.debug&&e())},error:function(e){x<"6.0.2"||(-1==B.state?e(B.data):L._fail=e)},checkJsApi:function(e){var n=function(e){var n=e.checkResult;for(var i in n){var t=v[i];t&&(n[t]=n[i],delete n[i])}return e};i("checkJsApi",{jsApiList:d(e.jsApiList)},(e._complete=function(e){if(M){var i=e.checkResult;i&&(e.checkResult=JSON.parse(i))}e=n(e)},e))},onMenuShareTimeline:function(e){t(h.onMenuShareTimeline,{complete:function(){i("shareTimeline",{title:e.title||I,desc:e.title||I,img_url:e.imgUrl||"",link:e.link||location.href,type:e.type||"link",data_url:e.dataUrl||""},e)}},e)},onMenuShareAppMessage:function(e){t(h.onMenuShareAppMessage,{complete:function(n){"favorite"===n.scene?i("sendAppMessage",{title:e.title||I,desc:e.desc||"",link:e.link||location.href,img_url:e.imgUrl||"",type:e.type||"link",data_url:e.dataUrl||""}):i("sendAppMessage",{title:e.title||I,desc:e.desc||"",link:e.link||location.href,img_url:e.imgUrl||"",type:e.type||"link",data_url:e.dataUrl||""},e)}},e)},onMenuShareQQ:function(e){t(h.onMenuShareQQ,{complete:function(){i("shareQQ",{title:e.title||I,desc:e.desc||"",img_url:e.imgUrl||"",link:e.link||location.href},e)}},e)},onMenuShareWeibo:function(e){t(h.onMenuShareWeibo,{complete:function(){i("shareWeiboApp",{title:e.title||I,desc:e.desc||"",img_url:e.imgUrl||"",link:e.link||location.href},e)}},e)},onMenuShareQZone:function(e){t(h.onMenuShareQZone,{complete:function(){i("shareQZone",{title:e.title||I,desc:e.desc||"",img_url:e.imgUrl||"",link:e.link||location.href},e)}},e)},updateTimelineShareData:function(e){i("updateTimelineShareData",{title:e.title,link:e.link,imgUrl:e.imgUrl},e)},updateAppMessageShareData:function(e){i("updateAppMessageShareData",{title:e.title,desc:e.desc,link:e.link,imgUrl:e.imgUrl},e)},startRecord:function(e){i("startRecord",{},e)},stopRecord:function(e){i("stopRecord",{},e)},onVoiceRecordEnd:function(e){t("onVoiceRecordEnd",e)},playVoice:function(e){i("playVoice",{localId:e.localId},e)},pauseVoice:function(e){i("pauseVoice",{localId:e.localId},e)},stopVoice:function(e){i("stopVoice",{localId:e.localId},e)},onVoicePlayEnd:function(e){t("onVoicePlayEnd",e)},uploadVoice:function(e){i("uploadVoice",{localId:e.localId,isShowProgressTips:0==e.isShowProgressTips?0:1},e)},downloadVoice:function(e){i("downloadVoice",{serverId:e.serverId,isShowProgressTips:0==e.isShowProgressTips?0:1},e)},translateVoice:function(e){i("translateVoice",{localId:e.localId,isShowProgressTips:0==e.isShowProgressTips?0:1},e)},chooseImage:function(e){i("chooseImage",{scene:"1|2",count:e.count||9,sizeType:e.sizeType||["original","compressed"],sourceType:e.sourceType||["album","camera"]},(e._complete=function(e){if(M){var n=e.localIds;try{n&&(e.localIds=JSON.parse(n))}catch(e){}}},e))},getLocation:function(e){},previewImage:function(e){i(h.previewImage,{current:e.current,urls:e.urls},e)},uploadImage:function(e){i("uploadImage",{localId:e.localId,isShowProgressTips:0==e.isShowProgressTips?0:1},e)},downloadImage:function(e){i("downloadImage",{serverId:e.serverId,isShowProgressTips:0==e.isShowProgressTips?0:1},e)},getLocalImgData:function(e){!1===O?(O=!0,i("getLocalImgData",{localId:e.localId},(e._complete=function(e){if(O=!1,E.length>0){var n=E.shift();wx.getLocalImgData(n)}},e))):E.push(e)},getNetworkType:function(e){var n=function(e){var n=e.errMsg;e.errMsg="getNetworkType:ok";var i=e.subtype;if(delete e.subtype,i)e.networkType=i;else{var t=n.indexOf(":"),o=n.substring(t+1);switch(o){case"wifi":case"edge":case"wwan":e.networkType=o;break;default:e.errMsg="getNetworkType:fail"}}return e};i("getNetworkType",{},(e._complete=function(e){e=n(e)},e))},openLocation:function(e){i("openLocation",{latitude:e.latitude,longitude:e.longitude,name:e.name||"",address:e.address||"",scale:e.scale||28,infoUrl:e.infoUrl||""},e)},getLocation:function(e){e=e||{},i(h.getLocation,{type:e.type||"wgs84"},(e._complete=function(e){delete e.type},e))},hideOptionMenu:function(e){i("hideOptionMenu",{},e)},showOptionMenu:function(e){i("showOptionMenu",{},e)},closeWindow:function(e){i("closeWindow",{},e=e||{})},hideMenuItems:function(e){i("hideMenuItems",{menuList:e.menuList},e)},showMenuItems:function(e){i("showMenuItems",{menuList:e.menuList},e)},hideAllNonBaseMenuItem:function(e){i("hideAllNonBaseMenuItem",{},e)},showAllNonBaseMenuItem:function(e){i("showAllNonBaseMenuItem",{},e)},scanQRCode:function(e){i("scanQRCode",{needResult:(e=e||{}).needResult||0,scanType:e.scanType||["qrCode","barCode"]},(e._complete=function(e){if(P){var n=e.resultStr;if(n){var i=JSON.parse(n);e.resultStr=i&&i.scan_code&&i.scan_code.scan_result}}},e))},openAddress:function(e){i(h.openAddress,{},(e._complete=function(e){e=a(e)},e))},openProductSpecificView:function(e){i(h.openProductSpecificView,{pid:e.productId,view_type:e.viewType||0,ext_info:e.extInfo},e)},addCard:function(e){for(var n=e.cardList,t=[],o=0,r=n.length;o<r;++o){var a=n[o],c={card_id:a.cardId,card_ext:a.cardExt};t.push(c)}i(h.addCard,{card_list:t},(e._complete=function(e){var n=e.card_list;if(n){for(var i=0,t=(n=JSON.parse(n)).length;i<t;++i){var o=n[i];o.cardId=o.card_id,o.cardExt=o.card_ext,o.isSuccess=!!o.is_succ,delete o.card_id,delete o.card_ext,delete o.is_succ}e.cardList=n,delete e.card_list}},e))},chooseCard:function(e){i("chooseCard",{app_id:C.appId,location_id:e.shopId||"",sign_type:e.signType||"SHA1",card_id:e.cardId||"",card_type:e.cardType||"",card_sign:e.cardSign,time_stamp:e.timestamp+"",nonce_str:e.nonceStr},(e._complete=function(e){e.cardList=e.choose_card_info,delete e.choose_card_info},e))},openCard:function(e){for(var n=e.cardList,t=[],o=0,r=n.length;o<r;++o){var a=n[o],c={card_id:a.cardId,code:a.code};t.push(c)}i(h.openCard,{card_list:t},e)},consumeAndShareCard:function(e){i(h.consumeAndShareCard,{consumedCardId:e.cardId,consumedCode:e.code},e)},chooseWXPay:function(e){i(h.chooseWXPay,r(e),e)},openEnterpriseRedPacket:function(e){i(h.openEnterpriseRedPacket,r(e),e)},startSearchBeacons:function(e){i(h.startSearchBeacons,{ticket:e.ticket},e)},stopSearchBeacons:function(e){i(h.stopSearchBeacons,{},e)},onSearchBeacons:function(e){t(h.onSearchBeacons,e)},openEnterpriseChat:function(e){i("openEnterpriseChat",{useridlist:e.userIds,chatname:e.groupName},e)},launchMiniProgram:function(e){i("launchMiniProgram",{targetAppId:e.targetAppId,path:g(e.path),envVersion:e.envVersion},e)},miniProgram:{navigateBack:function(e){e=e||{},f(function(){i("invokeMiniProgramAPI",{name:"navigateBack",arg:{delta:e.delta||1}},e)})},navigateTo:function(e){f(function(){i("invokeMiniProgramAPI",{name:"navigateTo",arg:{url:e.url}},e)})},redirectTo:function(e){f(function(){i("invokeMiniProgramAPI",{name:"redirectTo",arg:{url:e.url}},e)})},switchTab:function(e){f(function(){i("invokeMiniProgramAPI",{name:"switchTab",arg:{url:e.url}},e)})},reLaunch:function(e){f(function(){i("invokeMiniProgramAPI",{name:"reLaunch",arg:{url:e.url}},e)})},postMessage:function(e){f(function(){i("invokeMiniProgramAPI",{name:"postMessage",arg:e.data||{}},e)})},getEnv:function(n){f(function(){n({miniprogram:"miniprogram"===e.__wxjs_environment})})}}},b=1,R={};return S.addEventListener("error",function(e){if(!M){var n=e.target,i=n.tagName,t=n.src;if(("IMG"==i||"VIDEO"==i||"AUDIO"==i||"SOURCE"==i)&&-1!=t.indexOf("wxlocalresource://")){e.preventDefault(),e.stopPropagation();var o=n["wx-id"];if(o||(o=b++,n["wx-id"]=o),R[o])return;R[o]=!0,wx.ready(function(){wx.getLocalImgData({localId:t,success:function(e){n.src=e.localData}})})}}},!0),S.addEventListener("load",function(e){if(!M){var n=e.target,i=n.tagName;n.src;if("IMG"==i||"VIDEO"==i||"AUDIO"==i||"SOURCE"==i){var t=n["wx-id"];t&&(R[t]=!1)}}},!0),n&&(e.wx=e.jWeixin=N),N}});  
1 -// 获取微信公众号SDK权限  
2 -import base from '@/config/baseUrl';  
3 -import { isWechat } from '@/config/h5Utils';  
4 -  
5 -//获取地理位置  
6 -export const getLocation = () => {  
7 - return new Promise((resolve, reject) => {  
8 - jWeixin.ready(function () {  
9 - jWeixin.getLocation({  
10 - type: 'gcj02',  
11 - success: function (res) {  
12 - resolve(res);  
13 - },  
14 - fail: (err) => {  
15 - reject(err);  
16 - }  
17 - });  
18 - });  
19 - });  
20 -}  
21 -export const shareData = (info) => {  
22 - let item = {  
23 - title: info.title || base.share.title, // 分享标题  
24 - desc: info.desc || base.share.desc, // 分享描述  
25 - imgUrl: info.imgUrl || base.share.imgUrl, // 分享链接  
26 - link: info.link || base.share.link, // 分享图标  
27 - }  
28 - return item  
29 -}  
30 -//设置分享信息  
31 -export const setShare = (data, callback) => {  
32 - //配置校验成功后执行  
33 - jWeixin.ready(function () {  
34 - if (!data.link) {  
35 - let url = window.location.href;  
36 - let index = url.indexOf("?");  
37 - if (index != -1) {  
38 - if (url.indexOf("#") != -1 && url.indexOf("#") > index) {  
39 - url = url.substring(0, index) + url.substring(url.indexOf("#"));  
40 - } else {  
41 - url = url.substr(0, index);  
42 - }  
43 - }  
44 - data.link = url;  
45 - }  
46 - jWeixin.updateAppMessageShareData(shareData(data));  
47 - jWeixin.updateTimelineShareData(shareData(data));  
48 - });  
49 -}  
50 -//微信扫一扫  
51 -export const scanQRCode = ( callback,needResult = 0) => {  
52 - //配置校验成功后执行  
53 - jWeixin.ready(function () {  
54 - jWeixin.scanQRCode({  
55 - needResult: needResult, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,  
56 - scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有  
57 - success: function (res) {  
58 - callback && callback(res);  
59 - }  
60 - });  
61 - });  
62 -}  
63 -//获取微信JSSDK授权  
64 -window.onload = function () {  
65 - // 需配置公众号appId  
66 - if (!(base.publicAppId && isWechat())) {  
67 - return;  
68 - }  
69 - //获取当前页面地址  
70 - let url = window.location.href;  
71 - url = url.substring(0, url.indexOf("#"));  
72 - //获取微信公众号SDK权限的签名、随机数、时间戳  
73 - uni.$u.http.post("api/jWeixinConfig", {  
74 - url: url  
75 - }).then(res => {  
76 - // 微信SDK配置  
77 - jWeixin.config({  
78 - debug: false,  
79 - appId: base.publicAppId, // 必填,公众号的唯一标识  
80 - timestamp: res.timestamp, // 必填,生成签名的时间戳  
81 - nonceStr: res.noncestr, // 必填,生成签名的随机串  
82 - signature: res.signature,// 必填,签名  
83 - jsApiList: [  
84 - 'scanQRCode',  
85 - "getLocation",  
86 - "updateAppMessageShareData",  
87 - "updateTimelineShareData",  
88 - 'onMenuShareAppMessage', //旧的接口,即将废弃  
89 - 'onMenuShareTimeline' //旧的接口,即将废弃  
90 - ]  
91 - });  
92 - //设置分享内容  
93 - setShare();  
94 - });  
95 - //配置校验失败后执行  
96 - jWeixin.error(function (res) {  
97 - // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。  
98 - console.log(res);  
99 - });  
100 -};  
1 -/*  
2 - * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message  
3 - * Digest Algorithm, as defined in RFC 1321.  
4 - * Version 1.1 Copyright (C) Paul Johnston 1999 - 2002.  
5 - * Code also contributed by Greg Holt  
6 - * See http://pajhome.org.uk/site/legal.html for details.  
7 - */  
8 -  
9 -/*  
10 - * Add integers, wrapping at 2^32. This uses 16-bit operations internally  
11 - * to work around bugs in some JS interpreters.  
12 - */  
13 -function safe_add(x, y) {  
14 - var lsw = (x & 0xFFFF) + (y & 0xFFFF)  
15 - var msw = (x >> 16) + (y >> 16) + (lsw >> 16)  
16 - return (msw << 16) | (lsw & 0xFFFF)  
17 -}  
18 -  
19 -/*  
20 - * Bitwise rotate a 32-bit number to the left.  
21 - */  
22 -function rol(num, cnt) {  
23 - return (num << cnt) | (num >>> (32 - cnt))  
24 -}  
25 -  
26 -/*  
27 - * These functions implement the four basic operations the algorithm uses.  
28 - */  
29 -function cmn(q, a, b, x, s, t) {  
30 - return safe_add(rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b)  
31 -}  
32 -function ff(a, b, c, d, x, s, t) {  
33 - return cmn((b & c) | ((~b) & d), a, b, x, s, t)  
34 -}  
35 -function gg(a, b, c, d, x, s, t) {  
36 - return cmn((b & d) | (c & (~d)), a, b, x, s, t)  
37 -}  
38 -function hh(a, b, c, d, x, s, t) {  
39 - return cmn(b ^ c ^ d, a, b, x, s, t)  
40 -}  
41 -function ii(a, b, c, d, x, s, t) {  
42 - return cmn(c ^ (b | (~d)), a, b, x, s, t)  
43 -}  
44 -  
45 -/*  
46 - * Calculate the MD5 of an array of little-endian words, producing an array  
47 - * of little-endian words.  
48 - */  
49 -function coreMD5(x) {  
50 - var a = 1732584193  
51 - var b = -271733879  
52 - var c = -1732584194  
53 - var d = 271733878  
54 -  
55 - for (var i = 0; i < x.length; i += 16) {  
56 - var olda = a  
57 - var oldb = b  
58 - var oldc = c  
59 - var oldd = d  
60 -  
61 - a = ff(a, b, c, d, x[i + 0], 7, -680876936)  
62 - d = ff(d, a, b, c, x[i + 1], 12, -389564586)  
63 - c = ff(c, d, a, b, x[i + 2], 17, 606105819)  
64 - b = ff(b, c, d, a, x[i + 3], 22, -1044525330)  
65 - a = ff(a, b, c, d, x[i + 4], 7, -176418897)  
66 - d = ff(d, a, b, c, x[i + 5], 12, 1200080426)  
67 - c = ff(c, d, a, b, x[i + 6], 17, -1473231341)  
68 - b = ff(b, c, d, a, x[i + 7], 22, -45705983)  
69 - a = ff(a, b, c, d, x[i + 8], 7, 1770035416)  
70 - d = ff(d, a, b, c, x[i + 9], 12, -1958414417)  
71 - c = ff(c, d, a, b, x[i + 10], 17, -42063)  
72 - b = ff(b, c, d, a, x[i + 11], 22, -1990404162)  
73 - a = ff(a, b, c, d, x[i + 12], 7, 1804603682)  
74 - d = ff(d, a, b, c, x[i + 13], 12, -40341101)  
75 - c = ff(c, d, a, b, x[i + 14], 17, -1502002290)  
76 - b = ff(b, c, d, a, x[i + 15], 22, 1236535329)  
77 -  
78 - a = gg(a, b, c, d, x[i + 1], 5, -165796510)  
79 - d = gg(d, a, b, c, x[i + 6], 9, -1069501632)  
80 - c = gg(c, d, a, b, x[i + 11], 14, 643717713)  
81 - b = gg(b, c, d, a, x[i + 0], 20, -373897302)  
82 - a = gg(a, b, c, d, x[i + 5], 5, -701558691)  
83 - d = gg(d, a, b, c, x[i + 10], 9, 38016083)  
84 - c = gg(c, d, a, b, x[i + 15], 14, -660478335)  
85 - b = gg(b, c, d, a, x[i + 4], 20, -405537848)  
86 - a = gg(a, b, c, d, x[i + 9], 5, 568446438)  
87 - d = gg(d, a, b, c, x[i + 14], 9, -1019803690)  
88 - c = gg(c, d, a, b, x[i + 3], 14, -187363961)  
89 - b = gg(b, c, d, a, x[i + 8], 20, 1163531501)  
90 - a = gg(a, b, c, d, x[i + 13], 5, -1444681467)  
91 - d = gg(d, a, b, c, x[i + 2], 9, -51403784)  
92 - c = gg(c, d, a, b, x[i + 7], 14, 1735328473)  
93 - b = gg(b, c, d, a, x[i + 12], 20, -1926607734)  
94 -  
95 - a = hh(a, b, c, d, x[i + 5], 4, -378558)  
96 - d = hh(d, a, b, c, x[i + 8], 11, -2022574463)  
97 - c = hh(c, d, a, b, x[i + 11], 16, 1839030562)  
98 - b = hh(b, c, d, a, x[i + 14], 23, -35309556)  
99 - a = hh(a, b, c, d, x[i + 1], 4, -1530992060)  
100 - d = hh(d, a, b, c, x[i + 4], 11, 1272893353)  
101 - c = hh(c, d, a, b, x[i + 7], 16, -155497632)  
102 - b = hh(b, c, d, a, x[i + 10], 23, -1094730640)  
103 - a = hh(a, b, c, d, x[i + 13], 4, 681279174)  
104 - d = hh(d, a, b, c, x[i + 0], 11, -358537222)  
105 - c = hh(c, d, a, b, x[i + 3], 16, -722521979)  
106 - b = hh(b, c, d, a, x[i + 6], 23, 76029189)  
107 - a = hh(a, b, c, d, x[i + 9], 4, -640364487)  
108 - d = hh(d, a, b, c, x[i + 12], 11, -421815835)  
109 - c = hh(c, d, a, b, x[i + 15], 16, 530742520)  
110 - b = hh(b, c, d, a, x[i + 2], 23, -995338651)  
111 -  
112 - a = ii(a, b, c, d, x[i + 0], 6, -198630844)  
113 - d = ii(d, a, b, c, x[i + 7], 10, 1126891415)  
114 - c = ii(c, d, a, b, x[i + 14], 15, -1416354905)  
115 - b = ii(b, c, d, a, x[i + 5], 21, -57434055)  
116 - a = ii(a, b, c, d, x[i + 12], 6, 1700485571)  
117 - d = ii(d, a, b, c, x[i + 3], 10, -1894986606)  
118 - c = ii(c, d, a, b, x[i + 10], 15, -1051523)  
119 - b = ii(b, c, d, a, x[i + 1], 21, -2054922799)  
120 - a = ii(a, b, c, d, x[i + 8], 6, 1873313359)  
121 - d = ii(d, a, b, c, x[i + 15], 10, -30611744)  
122 - c = ii(c, d, a, b, x[i + 6], 15, -1560198380)  
123 - b = ii(b, c, d, a, x[i + 13], 21, 1309151649)  
124 - a = ii(a, b, c, d, x[i + 4], 6, -145523070)  
125 - d = ii(d, a, b, c, x[i + 11], 10, -1120210379)  
126 - c = ii(c, d, a, b, x[i + 2], 15, 718787259)  
127 - b = ii(b, c, d, a, x[i + 9], 21, -343485551)  
128 -  
129 - a = safe_add(a, olda)  
130 - b = safe_add(b, oldb)  
131 - c = safe_add(c, oldc)  
132 - d = safe_add(d, oldd)  
133 - }  
134 - return [a, b, c, d]  
135 -}  
136 -  
137 -/*  
138 - * Convert an array of little-endian words to a hex string.  
139 - */  
140 -function binl2hex(binarray) {  
141 - var hex_tab = "0123456789abcdef"  
142 - var str = ""  
143 - for (var i = 0; i < binarray.length * 4; i++) {  
144 - str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +  
145 - hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF)  
146 - }  
147 - return str  
148 -}  
149 -  
150 -/*  
151 - * Convert an array of little-endian words to a base64 encoded string.  
152 - */  
153 -function binl2b64(binarray) {  
154 - var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"  
155 - var str = ""  
156 - for (var i = 0; i < binarray.length * 32; i += 6) {  
157 - str += tab.charAt(((binarray[i >> 5] << (i % 32)) & 0x3F) |  
158 - ((binarray[i >> 5 + 1] >> (32 - i % 32)) & 0x3F))  
159 - }  
160 - return str  
161 -}  
162 -  
163 -/*  
164 - * Convert an 8-bit character string to a sequence of 16-word blocks, stored  
165 - * as an array, and append appropriate padding for MD4/5 calculation.  
166 - * If any of the characters are >255, the high byte is silently ignored.  
167 - */  
168 -function str2binl(str) {  
169 - var nblk = ((str.length + 8) >> 6) + 1 // number of 16-word blocks  
170 - var blks = new Array(nblk * 16)  
171 - for (var i = 0; i < nblk * 16; i++) blks[i] = 0  
172 - for (var i = 0; i < str.length; i++)  
173 - blks[i >> 2] |= (str.charCodeAt(i) & 0xFF) << ((i % 4) * 8)  
174 - blks[i >> 2] |= 0x80 << ((i % 4) * 8)  
175 - blks[nblk * 16 - 2] = str.length * 8  
176 - return blks  
177 -}  
178 -  
179 -/*  
180 - * Convert a wide-character string to a sequence of 16-word blocks, stored as  
181 - * an array, and append appropriate padding for MD4/5 calculation.  
182 - */  
183 -function strw2binl(str) {  
184 - var nblk = ((str.length + 4) >> 5) + 1 // number of 16-word blocks  
185 - var blks = new Array(nblk * 16)  
186 - for (var i = 0; i < nblk * 16; i++) blks[i] = 0  
187 - for (var i = 0; i < str.length; i++)  
188 - blks[i >> 1] |= str.charCodeAt(i) << ((i % 2) * 16)  
189 - blks[i >> 1] |= 0x80 << ((i % 2) * 16)  
190 - blks[nblk * 16 - 2] = str.length * 16  
191 - return blks  
192 -}  
193 -  
194 -/*  
195 - * External interface  
196 - */  
197 -function md5(str) { return binl2hex(coreMD5(str2binl(str))) }  
198 -function hexMD5w(str) { return binl2hex(coreMD5(strw2binl(str))) }  
199 -function b64MD5(str) { return binl2b64(coreMD5(str2binl(str))) }  
200 -function b64MD5w(str) { return binl2b64(coreMD5(strw2binl(str))) }  
201 -/* Backward compatibility */  
202 -function calcMD5(str) { return binl2hex(coreMD5(str2binl(str))) }  
203 -module.exports = md5  
1 -var ERROR_CONF={KEY_ERR:311,KEY_ERR_MSG:'key格式错误',PARAM_ERR:310,PARAM_ERR_MSG:'请求参数信息有误',SYSTEM_ERR:600,SYSTEM_ERR_MSG:'系统错误',WX_ERR_CODE:1000,WX_OK_CODE:200};var BASE_URL='https://apis.map.qq.com/ws/';var URL_SEARCH=BASE_URL+'place/v1/search';var URL_SUGGESTION=BASE_URL+'place/v1/suggestion';var URL_GET_GEOCODER=BASE_URL+'geocoder/v1/';var URL_CITY_LIST=BASE_URL+'district/v1/list';var URL_AREA_LIST=BASE_URL+'district/v1/getchildren';var URL_DISTANCE=BASE_URL+'distance/v1/';var URL_DIRECTION=BASE_URL+'direction/v1/';var MODE={driving:'driving',transit:'transit'};var EARTH_RADIUS=6378136.49;var Utils={safeAdd(x,y){var lsw=(x&0xffff)+(y&0xffff);var msw=(x>>16)+(y>>16)+(lsw>>16);return(msw<<16)|(lsw&0xffff)},bitRotateLeft(num,cnt){return(num<<cnt)|(num>>>(32-cnt))},md5cmn(q,a,b,x,s,t){return this.safeAdd(this.bitRotateLeft(this.safeAdd(this.safeAdd(a,q),this.safeAdd(x,t)),s),b)},md5ff(a,b,c,d,x,s,t){return this.md5cmn((b&c)|(~b&d),a,b,x,s,t)},md5gg(a,b,c,d,x,s,t){return this.md5cmn((b&d)|(c&~d),a,b,x,s,t)},md5hh(a,b,c,d,x,s,t){return this.md5cmn(b^c^d,a,b,x,s,t)},md5ii(a,b,c,d,x,s,t){return this.md5cmn(c^(b|~d),a,b,x,s,t)},binlMD5(x,len){x[len>>5]|=0x80<<(len%32);x[((len+64)>>>9<<4)+14]=len;var i;var olda;var oldb;var oldc;var oldd;var a=1732584193;var b=-271733879;var c=-1732584194;var d=271733878;for(i=0;i<x.length;i+=16){olda=a;oldb=b;oldc=c;oldd=d;a=this.md5ff(a,b,c,d,x[i],7,-680876936);d=this.md5ff(d,a,b,c,x[i+1],12,-389564586);c=this.md5ff(c,d,a,b,x[i+2],17,606105819);b=this.md5ff(b,c,d,a,x[i+3],22,-1044525330);a=this.md5ff(a,b,c,d,x[i+4],7,-176418897);d=this.md5ff(d,a,b,c,x[i+5],12,1200080426);c=this.md5ff(c,d,a,b,x[i+6],17,-1473231341);b=this.md5ff(b,c,d,a,x[i+7],22,-45705983);a=this.md5ff(a,b,c,d,x[i+8],7,1770035416);d=this.md5ff(d,a,b,c,x[i+9],12,-1958414417);c=this.md5ff(c,d,a,b,x[i+10],17,-42063);b=this.md5ff(b,c,d,a,x[i+11],22,-1990404162);a=this.md5ff(a,b,c,d,x[i+12],7,1804603682);d=this.md5ff(d,a,b,c,x[i+13],12,-40341101);c=this.md5ff(c,d,a,b,x[i+14],17,-1502002290);b=this.md5ff(b,c,d,a,x[i+15],22,1236535329);a=this.md5gg(a,b,c,d,x[i+1],5,-165796510);d=this.md5gg(d,a,b,c,x[i+6],9,-1069501632);c=this.md5gg(c,d,a,b,x[i+11],14,643717713);b=this.md5gg(b,c,d,a,x[i],20,-373897302);a=this.md5gg(a,b,c,d,x[i+5],5,-701558691);d=this.md5gg(d,a,b,c,x[i+10],9,38016083);c=this.md5gg(c,d,a,b,x[i+15],14,-660478335);b=this.md5gg(b,c,d,a,x[i+4],20,-405537848);a=this.md5gg(a,b,c,d,x[i+9],5,568446438);d=this.md5gg(d,a,b,c,x[i+14],9,-1019803690);c=this.md5gg(c,d,a,b,x[i+3],14,-187363961);b=this.md5gg(b,c,d,a,x[i+8],20,1163531501);a=this.md5gg(a,b,c,d,x[i+13],5,-1444681467);d=this.md5gg(d,a,b,c,x[i+2],9,-51403784);c=this.md5gg(c,d,a,b,x[i+7],14,1735328473);b=this.md5gg(b,c,d,a,x[i+12],20,-1926607734);a=this.md5hh(a,b,c,d,x[i+5],4,-378558);d=this.md5hh(d,a,b,c,x[i+8],11,-2022574463);c=this.md5hh(c,d,a,b,x[i+11],16,1839030562);b=this.md5hh(b,c,d,a,x[i+14],23,-35309556);a=this.md5hh(a,b,c,d,x[i+1],4,-1530992060);d=this.md5hh(d,a,b,c,x[i+4],11,1272893353);c=this.md5hh(c,d,a,b,x[i+7],16,-155497632);b=this.md5hh(b,c,d,a,x[i+10],23,-1094730640);a=this.md5hh(a,b,c,d,x[i+13],4,681279174);d=this.md5hh(d,a,b,c,x[i],11,-358537222);c=this.md5hh(c,d,a,b,x[i+3],16,-722521979);b=this.md5hh(b,c,d,a,x[i+6],23,76029189);a=this.md5hh(a,b,c,d,x[i+9],4,-640364487);d=this.md5hh(d,a,b,c,x[i+12],11,-421815835);c=this.md5hh(c,d,a,b,x[i+15],16,530742520);b=this.md5hh(b,c,d,a,x[i+2],23,-995338651);a=this.md5ii(a,b,c,d,x[i],6,-198630844);d=this.md5ii(d,a,b,c,x[i+7],10,1126891415);c=this.md5ii(c,d,a,b,x[i+14],15,-1416354905);b=this.md5ii(b,c,d,a,x[i+5],21,-57434055);a=this.md5ii(a,b,c,d,x[i+12],6,1700485571);d=this.md5ii(d,a,b,c,x[i+3],10,-1894986606);c=this.md5ii(c,d,a,b,x[i+10],15,-1051523);b=this.md5ii(b,c,d,a,x[i+1],21,-2054922799);a=this.md5ii(a,b,c,d,x[i+8],6,1873313359);d=this.md5ii(d,a,b,c,x[i+15],10,-30611744);c=this.md5ii(c,d,a,b,x[i+6],15,-1560198380);b=this.md5ii(b,c,d,a,x[i+13],21,1309151649);a=this.md5ii(a,b,c,d,x[i+4],6,-145523070);d=this.md5ii(d,a,b,c,x[i+11],10,-1120210379);c=this.md5ii(c,d,a,b,x[i+2],15,718787259);b=this.md5ii(b,c,d,a,x[i+9],21,-343485551);a=this.safeAdd(a,olda);b=this.safeAdd(b,oldb);c=this.safeAdd(c,oldc);d=this.safeAdd(d,oldd)}return[a,b,c,d]},binl2rstr(input){var i;var output='';var length32=input.length*32;for(i=0;i<length32;i+=8){output+=String.fromCharCode((input[i>>5]>>>(i%32))&0xff)}return output},rstr2binl(input){var i;var output=[];output[(input.length>>2)-1]=undefined;for(i=0;i<output.length;i+=1){output[i]=0}var length8=input.length*8;for(i=0;i<length8;i+=8){output[i>>5]|=(input.charCodeAt(i/8)&0xff)<<(i%32)}return output},rstrMD5(s){return this.binl2rstr(this.binlMD5(this.rstr2binl(s),s.length*8))},rstrHMACMD5(key,data){var i;var bkey=this.rstr2binl(key);var ipad=[];var opad=[];var hash;ipad[15]=opad[15]=undefined;if(bkey.length>16){bkey=this.binlMD5(bkey,key.length*8)}for(i=0;i<16;i+=1){ipad[i]=bkey[i]^0x36363636;opad[i]=bkey[i]^0x5c5c5c5c}hash=this.binlMD5(ipad.concat(this.rstr2binl(data)),512+data.length*8);return this.binl2rstr(this.binlMD5(opad.concat(hash),512+128))},rstr2hex(input){var hexTab='0123456789abcdef';var output='';var x;var i;for(i=0;i<input.length;i+=1){x=input.charCodeAt(i);output+=hexTab.charAt((x>>>4)&0x0f)+hexTab.charAt(x&0x0f)}return output},str2rstrUTF8(input){return unescape(encodeURIComponent(input))},rawMD5(s){return this.rstrMD5(this.str2rstrUTF8(s))},hexMD5(s){return this.rstr2hex(this.rawMD5(s))},rawHMACMD5(k,d){return this.rstrHMACMD5(this.str2rstrUTF8(k),str2rstrUTF8(d))},hexHMACMD5(k,d){return this.rstr2hex(this.rawHMACMD5(k,d))},md5(string,key,raw){if(!key){if(!raw){return this.hexMD5(string)}return this.rawMD5(string)}if(!raw){return this.hexHMACMD5(key,string)}return this.rawHMACMD5(key,string)},getSig(requestParam,sk,feature,mode){var sig=null;var requestArr=[];Object.keys(requestParam).sort().forEach(function(key){requestArr.push(key+'='+requestParam[key])});if(feature=='search'){sig='/ws/place/v1/search?'+requestArr.join('&')+sk}if(feature=='suggest'){sig='/ws/place/v1/suggestion?'+requestArr.join('&')+sk}if(feature=='reverseGeocoder'){sig='/ws/geocoder/v1/?'+requestArr.join('&')+sk}if(feature=='geocoder'){sig='/ws/geocoder/v1/?'+requestArr.join('&')+sk}if(feature=='getCityList'){sig='/ws/district/v1/list?'+requestArr.join('&')+sk}if(feature=='getDistrictByCityId'){sig='/ws/district/v1/getchildren?'+requestArr.join('&')+sk}if(feature=='calculateDistance'){sig='/ws/distance/v1/?'+requestArr.join('&')+sk}if(feature=='direction'){sig='/ws/direction/v1/'+mode+'?'+requestArr.join('&')+sk}sig=this.md5(sig);return sig},location2query(data){if(typeof data=='string'){return data}var query='';for(var i=0;i<data.length;i++){var d=data[i];if(!!query){query+=';'}if(d.location){query=query+d.location.lat+','+d.location.lng}if(d.latitude&&d.longitude){query=query+d.latitude+','+d.longitude}}return query},rad(d){return d*Math.PI/180.0},getEndLocation(location){var to=location.split(';');var endLocation=[];for(var i=0;i<to.length;i++){endLocation.push({lat:parseFloat(to[i].split(',')[0]),lng:parseFloat(to[i].split(',')[1])})}return endLocation},getDistance(latFrom,lngFrom,latTo,lngTo){var radLatFrom=this.rad(latFrom);var radLatTo=this.rad(latTo);var a=radLatFrom-radLatTo;var b=this.rad(lngFrom)-this.rad(lngTo);var distance=2*Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2)+Math.cos(radLatFrom)*Math.cos(radLatTo)*Math.pow(Math.sin(b/2),2)));distance=distance*EARTH_RADIUS;distance=Math.round(distance*10000)/10000;return parseFloat(distance.toFixed(0))},getWXLocation(success,fail,complete){wx.getLocation({type:'gcj02',success:success,fail:fail,complete:complete})},getLocationParam(location){if(typeof location=='string'){var locationArr=location.split(',');if(locationArr.length===2){location={latitude:location.split(',')[0],longitude:location.split(',')[1]}}else{location={}}}return location},polyfillParam(param){param.success=param.success||function(){};param.fail=param.fail||function(){};param.complete=param.complete||function(){}},checkParamKeyEmpty(param,key){if(!param[key]){var errconf=this.buildErrorConfig(ERROR_CONF.PARAM_ERR,ERROR_CONF.PARAM_ERR_MSG+key+'参数格式有误');param.fail(errconf);param.complete(errconf);return true}return false},checkKeyword(param){return!this.checkParamKeyEmpty(param,'keyword')},checkLocation(param){var location=this.getLocationParam(param.location);if(!location||!location.latitude||!location.longitude){var errconf=this.buildErrorConfig(ERROR_CONF.PARAM_ERR,ERROR_CONF.PARAM_ERR_MSG+' location参数格式有误');param.fail(errconf);param.complete(errconf);return false}return true},buildErrorConfig(errCode,errMsg){return{status:errCode,message:errMsg}},handleData(param,data,feature){if(feature=='search'){var searchResult=data.data;var searchSimplify=[];for(var i=0;i<searchResult.length;i++){searchSimplify.push({id:searchResult[i].id||null,title:searchResult[i].title||null,latitude:searchResult[i].location&&searchResult[i].location.lat||null,longitude:searchResult[i].location&&searchResult[i].location.lng||null,address:searchResult[i].address||null,category:searchResult[i].category||null,tel:searchResult[i].tel||null,adcode:searchResult[i].ad_info&&searchResult[i].ad_info.adcode||null,city:searchResult[i].ad_info&&searchResult[i].ad_info.city||null,district:searchResult[i].ad_info&&searchResult[i].ad_info.district||null,province:searchResult[i].ad_info&&searchResult[i].ad_info.province||null})}param.success(data,{searchResult:searchResult,searchSimplify:searchSimplify})}else if(feature=='suggest'){var suggestResult=data.data;var suggestSimplify=[];for(var i=0;i<suggestResult.length;i++){suggestSimplify.push({adcode:suggestResult[i].adcode||null,address:suggestResult[i].address||null,category:suggestResult[i].category||null,city:suggestResult[i].city||null,district:suggestResult[i].district||null,id:suggestResult[i].id||null,latitude:suggestResult[i].location&&suggestResult[i].location.lat||null,longitude:suggestResult[i].location&&suggestResult[i].location.lng||null,province:suggestResult[i].province||null,title:suggestResult[i].title||null,type:suggestResult[i].type||null})}param.success(data,{suggestResult:suggestResult,suggestSimplify:suggestSimplify})}else if(feature=='reverseGeocoder'){var reverseGeocoderResult=data.result;var reverseGeocoderSimplify={address:reverseGeocoderResult.address||null,latitude:reverseGeocoderResult.location&&reverseGeocoderResult.location.lat||null,longitude:reverseGeocoderResult.location&&reverseGeocoderResult.location.lng||null,adcode:reverseGeocoderResult.ad_info&&reverseGeocoderResult.ad_info.adcode||null,city:reverseGeocoderResult.address_component&&reverseGeocoderResult.address_component.city||null,district:reverseGeocoderResult.address_component&&reverseGeocoderResult.address_component.district||null,nation:reverseGeocoderResult.address_component&&reverseGeocoderResult.address_component.nation||null,province:reverseGeocoderResult.address_component&&reverseGeocoderResult.address_component.province||null,street:reverseGeocoderResult.address_component&&reverseGeocoderResult.address_component.street||null,street_number:reverseGeocoderResult.address_component&&reverseGeocoderResult.address_component.street_number||null,recommend:reverseGeocoderResult.formatted_addresses&&reverseGeocoderResult.formatted_addresses.recommend||null,rough:reverseGeocoderResult.formatted_addresses&&reverseGeocoderResult.formatted_addresses.rough||null};if(reverseGeocoderResult.pois){var pois=reverseGeocoderResult.pois;var poisSimplify=[];for(var i=0;i<pois.length;i++){poisSimplify.push({id:pois[i].id||null,title:pois[i].title||null,latitude:pois[i].location&&pois[i].location.lat||null,longitude:pois[i].location&&pois[i].location.lng||null,address:pois[i].address||null,category:pois[i].category||null,adcode:pois[i].ad_info&&pois[i].ad_info.adcode||null,city:pois[i].ad_info&&pois[i].ad_info.city||null,district:pois[i].ad_info&&pois[i].ad_info.district||null,province:pois[i].ad_info&&pois[i].ad_info.province||null})}param.success(data,{reverseGeocoderResult:reverseGeocoderResult,reverseGeocoderSimplify:reverseGeocoderSimplify,pois:pois,poisSimplify:poisSimplify})}else{param.success(data,{reverseGeocoderResult:reverseGeocoderResult,reverseGeocoderSimplify:reverseGeocoderSimplify})}}else if(feature=='geocoder'){var geocoderResult=data.result;var geocoderSimplify={title:geocoderResult.title||null,latitude:geocoderResult.location&&geocoderResult.location.lat||null,longitude:geocoderResult.location&&geocoderResult.location.lng||null,adcode:geocoderResult.ad_info&&geocoderResult.ad_info.adcode||null,province:geocoderResult.address_components&&geocoderResult.address_components.province||null,city:geocoderResult.address_components&&geocoderResult.address_components.city||null,district:geocoderResult.address_components&&geocoderResult.address_components.district||null,street:geocoderResult.address_components&&geocoderResult.address_components.street||null,street_number:geocoderResult.address_components&&geocoderResult.address_components.street_number||null,level:geocoderResult.level||null};param.success(data,{geocoderResult:geocoderResult,geocoderSimplify:geocoderSimplify})}else if(feature=='getCityList'){var provinceResult=data.result[0];var cityResult=data.result[1];var districtResult=data.result[2];param.success(data,{provinceResult:provinceResult,cityResult:cityResult,districtResult:districtResult})}else if(feature=='getDistrictByCityId'){var districtByCity=data.result[0];param.success(data,districtByCity)}else if(feature=='calculateDistance'){var calculateDistanceResult=data.result.elements;var distance=[];for(var i=0;i<calculateDistanceResult.length;i++){distance.push(calculateDistanceResult[i].distance)}param.success(data,{calculateDistanceResult:calculateDistanceResult,distance:distance})}else if(feature=='direction'){var direction=data.result.routes;param.success(data,direction)}else{param.success(data)}},buildWxRequestConfig(param,options,feature){var that=this;options.header={"content-type":"application/json"};options.method='GET';options.success=function(res){var data=res.data;if(data.status===0){that.handleData(param,data,feature)}else{param.fail(data)}};options.fail=function(res){res.statusCode=ERROR_CONF.WX_ERR_CODE;param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE,res.errMsg))};options.complete=function(res){var statusCode=+res.statusCode;switch(statusCode){case ERROR_CONF.WX_ERR_CODE:{param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE,res.errMsg));break}case ERROR_CONF.WX_OK_CODE:{var data=res.data;if(data.status===0){param.complete(data)}else{param.complete(that.buildErrorConfig(data.status,data.message))}break}default:{param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR,ERROR_CONF.SYSTEM_ERR_MSG))}}};return options},locationProcess(param,locationsuccess,locationfail,locationcomplete){var that=this;locationfail=locationfail||function(res){res.statusCode=ERROR_CONF.WX_ERR_CODE;param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE,res.errMsg))};locationcomplete=locationcomplete||function(res){if(res.statusCode==ERROR_CONF.WX_ERR_CODE){param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE,res.errMsg))}};if(!param.location){that.getWXLocation(locationsuccess,locationfail,locationcomplete)}else if(that.checkLocation(param)){var location=Utils.getLocationParam(param.location);locationsuccess(location)}}};class QQMapWX{constructor(options){if(!options.key){throw Error('key值不能为空')}this.key=options.key};search(options){var that=this;options=options||{};Utils.polyfillParam(options);if(!Utils.checkKeyword(options)){return}var requestParam={keyword:options.keyword,orderby:options.orderby||'_distance',page_size:options.page_size||10,page_index:options.page_index||1,output:'json',key:that.key};if(options.address_format){requestParam.address_format=options.address_format}if(options.filter){requestParam.filter=options.filter}var distance=options.distance||"1000";var auto_extend=options.auto_extend||1;var region=null;var rectangle=null;if(options.region){region=options.region}if(options.rectangle){rectangle=options.rectangle}var locationsuccess=function(result){if(region&&!rectangle){requestParam.boundary="region("+region+","+auto_extend+","+result.latitude+","+result.longitude+")";if(options.sig){requestParam.sig=Utils.getSig(requestParam,options.sig,'search')}}else if(rectangle&&!region){requestParam.boundary="rectangle("+rectangle+")";if(options.sig){requestParam.sig=Utils.getSig(requestParam,options.sig,'search')}}else{requestParam.boundary="nearby("+result.latitude+","+result.longitude+","+distance+","+auto_extend+")";if(options.sig){requestParam.sig=Utils.getSig(requestParam,options.sig,'search')}}wx.request(Utils.buildWxRequestConfig(options,{url:URL_SEARCH,data:requestParam},'search'))};Utils.locationProcess(options,locationsuccess)};getSuggestion(options){var that=this;options=options||{};Utils.polyfillParam(options);if(!Utils.checkKeyword(options)){return}var requestParam={keyword:options.keyword,region:options.region||'全国',region_fix:options.region_fix||0,policy:options.policy||0,page_size:options.page_size||10,page_index:options.page_index||1,get_subpois:options.get_subpois||0,output:'json',key:that.key};if(options.address_format){requestParam.address_format=options.address_format}if(options.filter){requestParam.filter=options.filter}if(options.location){var locationsuccess=function(result){requestParam.location=result.latitude+','+result.longitude;if(options.sig){requestParam.sig=Utils.getSig(requestParam,options.sig,'suggest')}wx.request(Utils.buildWxRequestConfig(options,{url:URL_SUGGESTION,data:requestParam},"suggest"))};Utils.locationProcess(options,locationsuccess)}else{if(options.sig){requestParam.sig=Utils.getSig(requestParam,options.sig,'suggest')}wx.request(Utils.buildWxRequestConfig(options,{url:URL_SUGGESTION,data:requestParam},"suggest"))}};reverseGeocoder(options){var that=this;options=options||{};Utils.polyfillParam(options);var requestParam={coord_type:options.coord_type||5,get_poi:options.get_poi||0,output:'json',key:that.key};if(options.poi_options){requestParam.poi_options=options.poi_options}var locationsuccess=function(result){requestParam.location=result.latitude+','+result.longitude;if(options.sig){requestParam.sig=Utils.getSig(requestParam,options.sig,'reverseGeocoder')}wx.request(Utils.buildWxRequestConfig(options,{url:URL_GET_GEOCODER,data:requestParam},'reverseGeocoder'))};Utils.locationProcess(options,locationsuccess)};geocoder(options){var that=this;options=options||{};Utils.polyfillParam(options);if(Utils.checkParamKeyEmpty(options,'address')){return}var requestParam={address:options.address,output:'json',key:that.key};if(options.region){requestParam.region=options.region}if(options.sig){requestParam.sig=Utils.getSig(requestParam,options.sig,'geocoder')}wx.request(Utils.buildWxRequestConfig(options,{url:URL_GET_GEOCODER,data:requestParam},'geocoder'))};getCityList(options){var that=this;options=options||{};Utils.polyfillParam(options);var requestParam={output:'json',key:that.key};if(options.sig){requestParam.sig=Utils.getSig(requestParam,options.sig,'getCityList')}wx.request(Utils.buildWxRequestConfig(options,{url:URL_CITY_LIST,data:requestParam},'getCityList'))};getDistrictByCityId(options){var that=this;options=options||{};Utils.polyfillParam(options);if(Utils.checkParamKeyEmpty(options,'id')){return}var requestParam={id:options.id||'',output:'json',key:that.key};if(options.sig){requestParam.sig=Utils.getSig(requestParam,options.sig,'getDistrictByCityId')}wx.request(Utils.buildWxRequestConfig(options,{url:URL_AREA_LIST,data:requestParam},'getDistrictByCityId'))};calculateDistance(options){var that=this;options=options||{};Utils.polyfillParam(options);if(Utils.checkParamKeyEmpty(options,'to')){return}var requestParam={mode:options.mode||'walking',to:Utils.location2query(options.to),output:'json',key:that.key};if(options.from){options.location=options.from}if(requestParam.mode=='straight'){var locationsuccess=function(result){var locationTo=Utils.getEndLocation(requestParam.to);var data={message:"query ok",result:{elements:[]},status:0};for(var i=0;i<locationTo.length;i++){data.result.elements.push({distance:Utils.getDistance(result.latitude,result.longitude,locationTo[i].lat,locationTo[i].lng),duration:0,from:{lat:result.latitude,lng:result.longitude},to:{lat:locationTo[i].lat,lng:locationTo[i].lng}})}var calculateResult=data.result.elements;var distanceResult=[];for(var i=0;i<calculateResult.length;i++){distanceResult.push(calculateResult[i].distance)}return options.success(data,{calculateResult:calculateResult,distanceResult:distanceResult})};Utils.locationProcess(options,locationsuccess)}else{var locationsuccess=function(result){requestParam.from=result.latitude+','+result.longitude;if(options.sig){requestParam.sig=Utils.getSig(requestParam,options.sig,'calculateDistance')}wx.request(Utils.buildWxRequestConfig(options,{url:URL_DISTANCE,data:requestParam},'calculateDistance'))};Utils.locationProcess(options,locationsuccess)}};direction(options){var that=this;options=options||{};Utils.polyfillParam(options);if(Utils.checkParamKeyEmpty(options,'to')){return}var requestParam={output:'json',key:that.key};if(typeof options.to=='string'){requestParam.to=options.to}else{requestParam.to=options.to.latitude+','+options.to.longitude}var SET_URL_DIRECTION=null;options.mode=options.mode||MODE.driving;SET_URL_DIRECTION=URL_DIRECTION+options.mode;if(options.from){options.location=options.from}if(options.mode==MODE.driving){if(options.from_poi){requestParam.from_poi=options.from_poi}if(options.heading){requestParam.heading=options.heading}if(options.speed){requestParam.speed=options.speed}if(options.accuracy){requestParam.accuracy=options.accuracy}if(options.road_type){requestParam.road_type=options.road_type}if(options.to_poi){requestParam.to_poi=options.to_poi}if(options.from_track){requestParam.from_track=options.from_track}if(options.waypoints){requestParam.waypoints=options.waypoints}if(options.policy){requestParam.policy=options.policy}if(options.plate_number){requestParam.plate_number=options.plate_number}}if(options.mode==MODE.transit){if(options.departure_time){requestParam.departure_time=options.departure_time}if(options.policy){requestParam.policy=options.policy}}var locationsuccess=function(result){requestParam.from=result.latitude+','+result.longitude;if(options.sig){requestParam.sig=Utils.getSig(requestParam,options.sig,'direction',options.mode)}wx.request(Utils.buildWxRequestConfig(options,{url:SET_URL_DIRECTION,data:requestParam},'direction'))};Utils.locationProcess(options,locationsuccess)}};module.exports=QQMapWX;  
publicLoginSubPage/other/code.vue renamed from pages/personal/code.vue
publicLoginSubPage/other/findPassword.vue renamed from pages/personal/findPassword.vue
publicLoginSubPage/other/set.vue renamed from pages/personal/set.vue
publicLoginSubPage/other/static/code.scss renamed from pages/personal/static/code.scss
publicLoginSubPage/other/static/findPassword.scss renamed from pages/personal/static/findPassword.scss
publicLoginSubPage/other/static/set.scss renamed from pages/personal/static/set.scss
@@ -122,22 +122,12 @@ export default { @@ -122,22 +122,12 @@ export default {
122 uni.showToast({ 122 uni.showToast({
123 title: '登录成功~', 123 title: '登录成功~',
124 icon: 'none' 124 icon: 'none'
  125 + }).then(res => {
  126 + uni.reLaunch({
  127 + url: '/pages/personal/personal'
125 }); 128 });
126 - this.saveUserInfo();  
127 - // #ifndef MP  
128 - // setTimeout(() => {  
129 - // uni.navigateBack();  
130 - // }, 500);  
131 - uni.switchTab({  
132 - url: '../personal/personal'  
133 - });  
134 - // #endif  
135 - // #ifdef MP  
136 - // uni.navigateBack();  
137 - uni.switchTab({  
138 - url: '../personal/personal'  
139 }); 129 });
140 - // #endif 130 + this.saveUserInfo();
141 } 131 }
142 }) 132 })
143 .catch(e => { 133 .catch(e => {
@@ -154,12 +144,12 @@ export default { @@ -154,12 +144,12 @@ export default {
154 }, 144 },
155 openCodeFunc() { 145 openCodeFunc() {
156 uni.navigateTo({ 146 uni.navigateTo({
157 - url: '../personal/code' 147 + url: '../other/code'
158 }); 148 });
159 }, 149 },
160 findPassrordFunc() { 150 findPassrordFunc() {
161 uni.navigateTo({ 151 uni.navigateTo({
162 - url: '../personal/findPassword' 152 + url: '../other/findPassword'
163 }); 153 });
164 }, 154 },
165 showPasswordMode() { 155 showPasswordMode() {
publicLoginSubPage/public/static/login.scss renamed from pages/public/static/login.scss
sysNotifySubPage/sysNotifyPage/notifyDetail.vue renamed from pages/systemNotify/notifyDetail.vue
sysNotifySubPage/sysNotifyPage/static/notifyDetail.scss renamed from pages/systemNotify/static/notifyDetail.scss
sysNotifySubPage/sysNotifyPage/static/systemNotify.scss renamed from pages/systemNotify/static/systemNotify.scss
sysNotifySubPage/sysNotifyPage/systemNotify.vue renamed from pages/systemNotify/systemNotify.vue
@@ -7,14 +7,13 @@ @@ -7,14 +7,13 @@
7 <u-form-item 7 <u-form-item
8 label="类型" 8 label="类型"
9 prop="userInfo.sex" 9 prop="userInfo.sex"
10 - borderBottom  
11 @click=" 10 @click="
12 showType = true; 11 showType = true;
13 hideKeyboard(); 12 hideKeyboard();
14 " 13 "
15 ref="item1" 14 ref="item1"
16 > 15 >
17 - <u--input v-model="model1.userInfo.type" placeholder="请选择类型" border="none"></u--input> 16 + <u--input v-model="model1.userInfo.type" placeholder="请选择类型" border="surround"></u--input>
18 <u-icon slot="right" name="arrow-right"></u-icon> 17 <u-icon slot="right" name="arrow-right"></u-icon>
19 </u-form-item> 18 </u-form-item>
20 </u--form> 19 </u--form>
@@ -38,19 +37,15 @@ @@ -38,19 +37,15 @@
38 </view> 37 </view>
39 </mescroll-body> 38 </mescroll-body>
40 </view> 39 </view>
41 - <f-tabbar></f-tabbar>  
42 </view> 40 </view>
43 </template> 41 </template>
44 42
45 <script> 43 <script>
46 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
47 import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'; 44 import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';
48 45
49 export default { 46 export default {
50 mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件) 47 mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件)
51 - components: {  
52 - fTabbar  
53 - }, 48 +
54 data() { 49 data() {
55 return { 50 return {
56 model1: { 51 model1: {
@@ -61,6 +56,10 @@ export default { @@ -61,6 +56,10 @@ export default {
61 showType: false, 56 showType: false,
62 actions: [ 57 actions: [
63 { 58 {
  59 + name: '全部',
  60 + value: ''
  61 + },
  62 + {
64 name: '会议', 63 name: '会议',
65 value: 'MEETING' 64 value: 'MEETING'
66 }, 65 },
1 -export default {  
2 - props: {  
3 - // 显示文字  
4 - title: {  
5 - type: String,  
6 - default: uni.$u.props.alert.title  
7 - },  
8 - // 主题,success/warning/info/error  
9 - type: {  
10 - type: String,  
11 - default: uni.$u.props.alert.type  
12 - },  
13 - // 辅助性文字  
14 - description: {  
15 - type: String,  
16 - default: uni.$u.props.alert.description  
17 - },  
18 - // 是否可关闭  
19 - closable: {  
20 - type: Boolean,  
21 - default: uni.$u.props.alert.closable  
22 - },  
23 - // 是否显示图标  
24 - showIcon: {  
25 - type: Boolean,  
26 - default: uni.$u.props.alert.showIcon  
27 - },  
28 - // 浅或深色调,light-浅色,dark-深色  
29 - effect: {  
30 - type: String,  
31 - default: uni.$u.props.alert.effect  
32 - },  
33 - // 文字是否居中  
34 - center: {  
35 - type: Boolean,  
36 - default: uni.$u.props.alert.center  
37 - },  
38 - // 字体大小  
39 - fontSize: {  
40 - type: [String, Number],  
41 - default: uni.$u.props.alert.fontSize  
42 - }  
43 - }  
44 -}  
1 -<template>  
2 - <u-transition  
3 - mode="fade"  
4 - :show="show"  
5 - >  
6 - <view  
7 - class="u-alert"  
8 - :class="[`u-alert--${type}--${effect}`]"  
9 - @tap.stop="clickHandler"  
10 - :style="[$u.addStyle(customStyle)]"  
11 - >  
12 - <view  
13 - class="u-alert__icon"  
14 - v-if="showIcon"  
15 - >  
16 - <u-icon  
17 - :name="iconName"  
18 - size="18"  
19 - :color="iconColor"  
20 - ></u-icon>  
21 - </view>  
22 - <view  
23 - class="u-alert__content"  
24 - :style="[{  
25 - paddingRight: closable ? '20px' : 0  
26 - }]"  
27 - >  
28 - <text  
29 - class="u-alert__content__title"  
30 - v-if="title"  
31 - :style="[{  
32 - fontSize: $u.addUnit(fontSize),  
33 - textAlign: center ? 'center' : 'left'  
34 - }]"  
35 - :class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"  
36 - >{{ title }}</text>  
37 - <text  
38 - class="u-alert__content__desc"  
39 - v-if="description"  
40 - :style="[{  
41 - fontSize: $u.addUnit(fontSize),  
42 - textAlign: center ? 'center' : 'left'  
43 - }]"  
44 - :class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"  
45 - >{{ description }}</text>  
46 - </view>  
47 - <view  
48 - class="u-alert__close"  
49 - v-if="closable"  
50 - @tap.stop="closeHandler"  
51 - >  
52 - <u-icon  
53 - name="close"  
54 - :color="iconColor"  
55 - size="15"  
56 - ></u-icon>  
57 - </view>  
58 - </view>  
59 - </u-transition>  
60 -</template>  
61 -  
62 -<script>  
63 - import props from './props.js';  
64 - /**  
65 - * Alert 警告提示  
66 - * @description 警告提示,展现需要关注的信息。  
67 - * @tutorial https://www.uviewui.com/components/alertTips.html  
68 - *  
69 - * @property {String} title 显示的文字  
70 - * @property {String} type 使用预设的颜色 (默认 'warning' )  
71 - * @property {String} description 辅助性文字,颜色比title浅一点,字号也小一点,可选  
72 - * @property {Boolean} closable 关闭按钮(默认为叉号icon图标) (默认 false )  
73 - * @property {Boolean} showIcon 是否显示左边的辅助图标 ( 默认 false )  
74 - * @property {String} effect 多图时,图片缩放裁剪的模式 (默认 'light' )  
75 - * @property {Boolean} center 文字是否居中 (默认 false )  
76 - * @property {String | Number} fontSize 字体大小 (默认 14 )  
77 - * @property {Object} customStyle 定义需要用到的外部样式  
78 - * @event {Function} click 点击组件时触发  
79 - * @example <u-alert :title="title" type = "warning" :closable="closable" :description = "description"></u-alert>  
80 - */  
81 - export default {  
82 - name: 'u-alert',  
83 - mixins: [uni.$u.mpMixin, uni.$u.mixin, props],  
84 - data() {  
85 - return {  
86 - show: true  
87 - }  
88 - },  
89 - computed: {  
90 - iconColor() {  
91 - return this.effect === 'light' ? this.type : '#fff'  
92 - },  
93 - // 不同主题对应不同的图标  
94 - iconName() {  
95 - switch (this.type) {  
96 - case 'success':  
97 - return 'checkmark-circle-fill';  
98 - break;  
99 - case 'error':  
100 - return 'close-circle-fill';  
101 - break;  
102 - case 'warning':  
103 - return 'error-circle-fill';  
104 - break;  
105 - case 'info':  
106 - return 'info-circle-fill';  
107 - break;  
108 - case 'primary':  
109 - return 'more-circle-fill';  
110 - break;  
111 - default:  
112 - return 'error-circle-fill';  
113 - }  
114 - }  
115 - },  
116 - methods: {  
117 - // 点击内容  
118 - clickHandler() {  
119 - this.$emit('click')  
120 - },  
121 - // 点击关闭按钮  
122 - closeHandler() {  
123 - this.show = false  
124 - }  
125 - }  
126 - }  
127 -</script>  
128 -  
129 -<style lang="scss" scoped>  
130 - @import "../../libs/css/components.scss";  
131 -  
132 - .u-alert {  
133 - position: relative;  
134 - background-color: $u-primary;  
135 - padding: 8px 10px;  
136 - @include flex(row);  
137 - align-items: center;  
138 - border-top-left-radius: 4px;  
139 - border-top-right-radius: 4px;  
140 - border-bottom-left-radius: 4px;  
141 - border-bottom-right-radius: 4px;  
142 -  
143 - &--primary--dark {  
144 - background-color: $u-primary;  
145 - }  
146 -  
147 - &--primary--light {  
148 - background-color: #ecf5ff;  
149 - }  
150 -  
151 - &--error--dark {  
152 - background-color: $u-error;  
153 - }  
154 -  
155 - &--error--light {  
156 - background-color: #FEF0F0;  
157 - }  
158 -  
159 - &--success--dark {  
160 - background-color: $u-success;  
161 - }  
162 -  
163 - &--success--light {  
164 - background-color: #f5fff0;  
165 - }  
166 -  
167 - &--warning--dark {  
168 - background-color: $u-warning;  
169 - }  
170 -  
171 - &--warning--light {  
172 - background-color: #FDF6EC;  
173 - }  
174 -  
175 - &--info--dark {  
176 - background-color: $u-info;  
177 - }  
178 -  
179 - &--info--light {  
180 - background-color: #f4f4f5;  
181 - }  
182 -  
183 - &__icon {  
184 - margin-right: 5px;  
185 - }  
186 -  
187 - &__content {  
188 - @include flex(column);  
189 - flex: 1;  
190 -  
191 - &__title {  
192 - color: $u-main-color;  
193 - font-size: 14px;  
194 - font-weight: bold;  
195 - color: #fff;  
196 - margin-bottom: 2px;  
197 - }  
198 -  
199 - &__desc {  
200 - color: $u-main-color;  
201 - font-size: 14px;  
202 - flex-wrap: wrap;  
203 - color: #fff;  
204 - }  
205 - }  
206 -  
207 - &__title--dark,  
208 - &__desc--dark {  
209 - color: #FFFFFF;  
210 - }  
211 -  
212 - &__text--primary--light,  
213 - &__text--primary--light {  
214 - color: $u-primary;  
215 - }  
216 -  
217 - &__text--success--light,  
218 - &__text--success--light {  
219 - color: $u-success;  
220 - }  
221 -  
222 - &__text--warning--light,  
223 - &__text--warning--light {  
224 - color: $u-warning;  
225 - }  
226 -  
227 - &__text--error--light,  
228 - &__text--error--light {  
229 - color: $u-error;  
230 - }  
231 -  
232 - &__text--info--light,  
233 - &__text--info--light {  
234 - color: $u-info;  
235 - }  
236 -  
237 - &__close {  
238 - position: absolute;  
239 - top: 11px;  
240 - right: 10px;  
241 - }  
242 - }  
243 -</style>  
1 -export default {  
2 - props: {  
3 - // 最大输入长度  
4 - maxlength: {  
5 - type: [String, Number],  
6 - default: uni.$u.props.codeInput.maxlength  
7 - },  
8 - // 是否用圆点填充  
9 - dot: {  
10 - type: Boolean,  
11 - default: uni.$u.props.codeInput.dot  
12 - },  
13 - // 显示模式,box-盒子模式,line-底部横线模式  
14 - mode: {  
15 - type: String,  
16 - default: uni.$u.props.codeInput.mode  
17 - },  
18 - // 是否细边框  
19 - hairline: {  
20 - type: Boolean,  
21 - default: uni.$u.props.codeInput.hairline  
22 - },  
23 - // 字符间的距离  
24 - space: {  
25 - type: [String, Number],  
26 - default: uni.$u.props.codeInput.space  
27 - },  
28 - // 预置值  
29 - value: {  
30 - type: [String, Number],  
31 - default: uni.$u.props.codeInput.value  
32 - },  
33 - // 是否自动获取焦点  
34 - focus: {  
35 - type: Boolean,  
36 - default: uni.$u.props.codeInput.focus  
37 - },  
38 - // 字体是否加粗  
39 - bold: {  
40 - type: Boolean,  
41 - default: uni.$u.props.codeInput.bold  
42 - },  
43 - // 字体颜色  
44 - color: {  
45 - type: String,  
46 - default: uni.$u.props.codeInput.color  
47 - },  
48 - // 字体大小  
49 - fontSize: {  
50 - type: [String, Number],  
51 - default: uni.$u.props.codeInput.fontSize  
52 - },  
53 - // 输入框的大小,宽等于高  
54 - size: {  
55 - type: [String, Number],  
56 - default: uni.$u.props.codeInput.size  
57 - },  
58 - // 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true  
59 - disabledKeyboard: {  
60 - type: Boolean,  
61 - default: uni.$u.props.codeInput.disabledKeyboard  
62 - },  
63 - // 边框和线条颜色  
64 - borderColor: {  
65 - type: String,  
66 - default: uni.$u.props.codeInput.borderColor  
67 - },  
68 - // 是否禁止输入"."符号  
69 - disabledDot: {  
70 - type: Boolean,  
71 - default: uni.$u.props.codeInput.disabledDot  
72 - }  
73 - }  
74 -}  
1 -<template>  
2 - <view class="u-code-input">  
3 - <view  
4 - class="u-code-input__item"  
5 - :style="[itemStyle(index)]"  
6 - v-for="(item, index) in codeLength"  
7 - :key="index"  
8 - >  
9 - <view  
10 - class="u-code-input__item__dot"  
11 - v-if="dot && codeArray.length > index"  
12 - ></view>  
13 - <text  
14 - v-else  
15 - :style="{  
16 - fontSize: $u.addUnit(fontSize),  
17 - fontWeight: bold ? 'bold' : 'normal',  
18 - color: color  
19 - }"  
20 - >{{codeArray[index]}}</text>  
21 - <view  
22 - class="u-code-input__item__line"  
23 - v-if="mode === 'line'"  
24 - :style="[lineStyle]"  
25 - ></view>  
26 - </view>  
27 - <input  
28 - :disabled="disabledKeyboard"  
29 - type="number"  
30 - :focus="focus"  
31 - :value="inputValue"  
32 - :maxlength="maxlength"  
33 - class="u-code-input__input"  
34 - @input="inputHandler"  
35 - :style="{  
36 - height: $u.addUnit(size)  
37 - }"  
38 - />  
39 - </view>  
40 -</template>  
41 -  
42 -<script>  
43 - import props from './props.js';  
44 - /**  
45 - * CodeInput 验证码输入  
46 - * @description 该组件一般用于验证用户短信验证码的场景,也可以结合uView的键盘组件使用  
47 - * @tutorial https://www.uviewui.com/components/codeInput.html  
48 - * @property {String | Number} maxlength 最大输入长度 (默认 6 )  
49 - * @property {Boolean} dot 是否用圆点填充 (默认 false )  
50 - * @property {String} mode 显示模式,box-盒子模式,line-底部横线模式 (默认 'box' )  
51 - * @property {Boolean} hairline 是否细边框 (默认 false )  
52 - * @property {String | Number} space 字符间的距离 (默认 10 )  
53 - * @property {String | Number} value 预置值  
54 - * @property {Boolean} focus 是否自动获取焦点 (默认 false )  
55 - * @property {Boolean} bold 字体和输入横线是否加粗 (默认 false )  
56 - * @property {String} color 字体颜色 (默认 '#606266' )  
57 - * @property {String | Number} fontSize 字体大小,单位px (默认 18 )  
58 - * @property {String | Number} size 输入框的大小,宽等于高 (默认 35 )  
59 - * @property {Boolean} disabledKeyboard 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true (默认 false )  
60 - * @property {String} borderColor 边框和线条颜色 (默认 '#c9cacc' )  
61 - * @property {Boolean} disabledDot 是否禁止输入"."符号 (默认 true )  
62 - *  
63 - * @event {Function} change 输入内容发生改变时触发,具体见上方说明 value:当前输入的值  
64 - * @event {Function} finish 输入字符个数达maxlength值时触发,见上方说明 value:当前输入的值  
65 - * @example <u-code-input v-model="value4" :focus="true"></u-code-input>  
66 - */  
67 - export default {  
68 - name: 'u-code-input',  
69 - mixins: [uni.$u.mpMixin, uni.$u.mixin, props],  
70 - data() {  
71 - return {  
72 - inputValue: ''  
73 - }  
74 - },  
75 - watch: {  
76 - value: {  
77 - immediate: true,  
78 - handler(val) {  
79 - // 转为字符串,超出部分截掉  
80 - this.inputValue = String(val).substring(0, this.maxlength)  
81 - }  
82 - },  
83 - },  
84 - computed: {  
85 - // 根据长度,循环输入框的个数,因为头条小程序数值不能用于v-for  
86 - codeLength() {  
87 - return new Array(Number(this.maxlength))  
88 - },  
89 - // 循环item的样式  
90 - itemStyle() {  
91 - return index => {  
92 - const addUnit = uni.$u.addUnit  
93 - const style = {  
94 - width: addUnit(this.size),  
95 - height: addUnit(this.size)  
96 - }  
97 - // 盒子模式下,需要额外进行处理  
98 - if (this.mode === 'box') {  
99 - // 设置盒子的边框,如果是细边框,则设置为0.5px宽度  
100 - style.border = `${this.hairline ? 0.5 : 1}px solid ${this.borderColor}`  
101 - // 如果盒子间距为0的话  
102 - if (uni.$u.getPx(this.space) === 0) {  
103 - // 给第一和最后一个盒子设置圆角  
104 - if (index === 0) {  
105 - style.borderTopLeftRadius = '3px'  
106 - style.borderBottomLeftRadius = '3px'  
107 - }  
108 - if (index === this.codeLength.length - 1) {  
109 - style.borderTopRightRadius = '3px'  
110 - style.borderBottomRightRadius = '3px'  
111 - }  
112 - // 最后一个盒子的右边框需要保留  
113 - if (index !== this.codeLength.length - 1) {  
114 - style.borderRight = 'none'  
115 - }  
116 - }  
117 - }  
118 - if (index !== this.codeLength.length - 1) {  
119 - // 设置验证码字符之间的距离,通过margin-right设置,最后一个字符,无需右边框  
120 - style.marginRight = addUnit(this.space)  
121 - } else {  
122 - // 最后一个盒子的有边框需要保留  
123 - style.marginRight = 0  
124 - }  
125 -  
126 - return style  
127 - }  
128 - },  
129 - // 将输入的值,转为数组,给item历遍时,根据当前的索引显示数组的元素  
130 - codeArray() {  
131 - return String(this.inputValue).split('')  
132 - },  
133 - // 下划线模式下,横线的样式  
134 - lineStyle() {  
135 - const style = {}  
136 - style.height = this.hairline ? '2px' : '4px'  
137 - style.width = uni.$u.addUnit(this.size)  
138 - // 线条模式下,背景色即为边框颜色  
139 - style.backgroundColor = this.borderColor  
140 - return style  
141 - }  
142 - },  
143 - methods: {  
144 - // 监听输入框的值发生变化  
145 - inputHandler(e) {  
146 - const value = e.detail.value  
147 - this.inputValue = value  
148 - // 是否允许输入“.”符号  
149 - if(this.disabledDot) {  
150 - this.$nextTick(() => {  
151 - this.inputValue = value.replace('.', '')  
152 - })  
153 - }  
154 - // 未达到maxlength之前,发送change事件,达到后发送finish事件  
155 - this.$emit('change', value)  
156 - // 修改通过v-model双向绑定的值  
157 - this.$emit('input', value)  
158 - // 达到用户指定输入长度时,发出完成事件  
159 - if (String(value).length >= Number(this.maxlength)) {  
160 - this.$emit('finish', value)  
161 - }  
162 - }  
163 - }  
164 - }  
165 -</script>  
166 -  
167 -<style lang="scss" scoped>  
168 - @import "../../libs/css/components.scss";  
169 -  
170 - .u-code-input {  
171 - @include flex;  
172 - position: relative;  
173 - overflow: hidden;  
174 -  
175 - &__item {  
176 - @include flex;  
177 - justify-content: center;  
178 - align-items: center;  
179 -  
180 - &__text {  
181 - font-size: 15px;  
182 - color: $u-content-color;  
183 - }  
184 -  
185 - &__dot {  
186 - width: 7px;  
187 - height: 7px;  
188 - border-radius: 100px;  
189 - background-color: $u-content-color;  
190 - }  
191 -  
192 - &__line {  
193 - position: absolute;  
194 - bottom: 0;  
195 - height: 4px;  
196 - border-radius: 100px;  
197 - width: 40px;  
198 - background-color: $u-content-color;  
199 - }  
200 - }  
201 -  
202 - &__input {  
203 - // 之所以需要input输入框,是因为有它才能唤起键盘  
204 - // 这里将它设置为两倍的屏幕宽度,再将左边的一半移出屏幕,为了不让用户看到输入的内容  
205 - position: absolute;  
206 - left: -750rpx;  
207 - width: 1500rpx;  
208 - top: 0;  
209 - background-color: transparent;  
210 - text-align: left;  
211 - }  
212 - }  
213 -</style>  
1 -export default {  
2 - props: {  
3 - // 倒计时总秒数  
4 - seconds: {  
5 - type: [String, Number],  
6 - default: uni.$u.props.code.seconds  
7 - },  
8 - // 尚未开始时提示  
9 - startText: {  
10 - type: String,  
11 - default: uni.$u.props.code.startText  
12 - },  
13 - // 正在倒计时中的提示  
14 - changeText: {  
15 - type: String,  
16 - default: uni.$u.props.code.changeText  
17 - },  
18 - // 倒计时结束时的提示  
19 - endText: {  
20 - type: String,  
21 - default: uni.$u.props.code.endText  
22 - },  
23 - // 是否在H5刷新或各端返回再进入时继续倒计时  
24 - keepRunning: {  
25 - type: Boolean,  
26 - default: uni.$u.props.code.keepRunning  
27 - },  
28 - // 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了  
29 - uniqueKey: {  
30 - type: String,  
31 - default: uni.$u.props.code.uniqueKey  
32 - }  
33 - }  
34 -}  
1 -<template>  
2 - <view class="u-code">  
3 - <!-- 此组件功能由js完成,无需写html逻辑 -->  
4 - </view>  
5 -</template>  
6 -  
7 -<script>  
8 - import props from './props.js';  
9 - /**  
10 - * Code 验证码输入框  
11 - * @description 考虑到用户实际发送验证码的场景,可能是一个按钮,也可能是一段文字,提示语各有不同,所以本组件 不提供界面显示,只提供提示语,由用户将提示语嵌入到具体的场景  
12 - * @tutorial https://www.uviewui.com/components/code.html  
13 - * @property {String | Number} seconds 倒计时所需的秒数(默认 60 )  
14 - * @property {String} startText 开始前的提示语,见官网说明(默认 '获取验证码' )  
15 - * @property {String} changeText 倒计时期间的提示语,必须带有字母"x",见官网说明(默认 'X秒重新获取' )  
16 - * @property {String} endText 倒计结束的提示语,见官网说明(默认 '重新获取' )  
17 - * @property {Boolean} keepRunning 是否在H5刷新或各端返回再进入时继续倒计时( 默认false )  
18 - * @property {String} uniqueKey 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了  
19 - *  
20 - * @event {Function} change 倒计时期间,每秒触发一次  
21 - * @event {Function} start 开始倒计时触发  
22 - * @event {Function} end 结束倒计时触发  
23 - * @example <u-code ref="uCode" @change="codeChange" seconds="20"></u-code>  
24 - */  
25 - export default {  
26 - name: "u-code",  
27 - mixins: [uni.$u.mpMixin, uni.$u.mixin,props],  
28 - data() {  
29 - return {  
30 - secNum: this.seconds,  
31 - timer: null,  
32 - canGetCode: true, // 是否可以执行验证码操作  
33 - }  
34 - },  
35 - mounted() {  
36 - this.checkKeepRunning()  
37 - },  
38 - watch: {  
39 - seconds: {  
40 - immediate: true,  
41 - handler(n) {  
42 - this.secNum = n  
43 - }  
44 - }  
45 - },  
46 - methods: {  
47 - checkKeepRunning() {  
48 - // 获取上一次退出页面(H5还包括刷新)时的时间戳,如果没有上次的保存,此值可能为空  
49 - let lastTimestamp = Number(uni.getStorageSync(this.uniqueKey + '_$uCountDownTimestamp'))  
50 - if(!lastTimestamp) return this.changeEvent(this.startText)  
51 - // 当前秒的时间戳  
52 - let nowTimestamp = Math.floor((+ new Date()) / 1000)  
53 - // 判断当前的时间戳,是否小于上一次的本该按设定结束,却提前结束的时间戳  
54 - if(this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {  
55 - // 剩余尚未执行完的倒计秒数  
56 - this.secNum = lastTimestamp - nowTimestamp  
57 - // 清除本地保存的变量  
58 - uni.removeStorageSync(this.uniqueKey + '_$uCountDownTimestamp')  
59 - // 开始倒计时  
60 - this.start()  
61 - } else {  
62 - // 如果不存在需要继续上一次的倒计时,执行正常的逻辑  
63 - this.changeEvent(this.startText)  
64 - }  
65 - },  
66 - // 开始倒计时  
67 - start() {  
68 - // 防止快速点击获取验证码的按钮而导致内部产生多个定时器导致混乱  
69 - if(this.timer) {  
70 - clearInterval(this.timer)  
71 - this.timer = null  
72 - }  
73 - this.$emit('start')  
74 - this.canGetCode = false  
75 - // 这里放这句,是为了一开始时就提示,否则要等setInterval的1秒后才会有提示  
76 - this.changeEvent(this.changeText.replace(/x|X/, this.secNum))  
77 - this.setTimeToStorage()  
78 - this.timer = setInterval(() => {  
79 - if (--this.secNum) {  
80 - // 用当前倒计时的秒数替换提示字符串中的"x"字母  
81 - this.changeEvent(this.changeText.replace(/x|X/, this.secNum))  
82 - } else {  
83 - clearInterval(this.timer)  
84 - this.timer = null  
85 - this.changeEvent(this.endText)  
86 - this.secNum = this.seconds  
87 - this.$emit('end')  
88 - this.canGetCode = true  
89 - }  
90 - }, 1000)  
91 - },  
92 - // 重置,可以让用户再次获取验证码  
93 - reset() {  
94 - this.canGetCode = true  
95 - clearInterval(this.timer)  
96 - this.secNum = this.seconds  
97 - this.changeEvent(this.endText)  
98 - },  
99 - changeEvent(text) {  
100 - this.$emit('change', text)  
101 - },  
102 - // 保存时间戳,为了防止倒计时尚未结束,H5刷新或者各端的右上角返回上一页再进来  
103 - setTimeToStorage() {  
104 - if(!this.keepRunning || !this.timer) return  
105 - // 记录当前的时间戳,为了下次进入页面,如果还在倒计时内的话,继续倒计时  
106 - // 倒计时尚未结束,结果大于0;倒计时已经开始,就会小于初始值,如果等于初始值,说明没有开始倒计时,无需处理  
107 - if(this.secNum > 0 && this.secNum <= this.seconds) {  
108 - // 获取当前时间戳(+ new Date()为特殊写法),除以1000变成秒,再去除小数部分  
109 - let nowTimestamp = Math.floor((+ new Date()) / 1000)  
110 - // 将本该结束时候的时间戳保存起来 => 当前时间戳 + 剩余的秒数  
111 - uni.setStorage({  
112 - key: this.uniqueKey + '_$uCountDownTimestamp',  
113 - data: nowTimestamp + Number(this.secNum)  
114 - })  
115 - }  
116 - }  
117 - },  
118 - // 组件销毁的时候,清除定时器,否则定时器会继续存在,系统不会自动清除  
119 - beforeDestroy() {  
120 - this.setTimeToStorage()  
121 - clearTimeout(this.timer)  
122 - this.timer = null  
123 - }  
124 - }  
125 -</script>  
126 -  
127 -<style lang="scss" scoped>  
128 - @import "../../libs/css/components.scss";  
129 -</style>  
1 -export default {  
2 - props: {  
3 - // 宫格的name  
4 - name: {  
5 - type: [String, Number, null],  
6 - default: uni.$u.props.gridItem.name  
7 - },  
8 - // 背景颜色  
9 - bgColor: {  
10 - type: String,  
11 - default: uni.$u.props.gridItem.bgColor  
12 - }  
13 - }  
14 -}  
1 -<template>  
2 - <!-- #ifndef APP-NVUE -->  
3 - <view  
4 - class="u-grid-item"  
5 - hover-class="u-grid-item--hover-class"  
6 - :hover-stay-time="200"  
7 - @tap="clickHandler"  
8 - :class="classes"  
9 - :style="[itemStyle]"  
10 - >  
11 - <slot />  
12 - </view>  
13 - <!-- #endif -->  
14 - <!-- #ifdef APP-NVUE -->  
15 - <view  
16 - class="u-grid-item"  
17 - :hover-stay-time="200"  
18 - @tap="clickHandler"  
19 - :class="classes"  
20 - :style="[itemStyle]"  
21 - >  
22 - <slot />  
23 - </view>  
24 - <!-- #endif -->  
25 -</template>  
26 -  
27 -<script>  
28 - import props from './props.js';  
29 - /**  
30 - * gridItem 提示  
31 - * @description 宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。搭配u-grid使用  
32 - * @tutorial https://www.uviewui.com/components/grid.html  
33 - * @property {String | Number} name 宫格的name ( 默认 null )  
34 - * @property {String} bgColor 宫格的背景颜色 (默认 'transparent' )  
35 - * @property {Object} customStyle 自定义样式,对象形式  
36 - * @event {Function} click 点击宫格触发  
37 - * @example <u-grid-item></u-grid-item>  
38 - */  
39 - export default {  
40 - name: "u-grid-item",  
41 - mixins: [uni.$u.mpMixin, uni.$u.mixin,props],  
42 - data() {  
43 - return {  
44 - parentData: {  
45 - col: 3, // 父组件划分的宫格数  
46 - border: true, // 是否显示边框,根据父组件决定  
47 - },  
48 - // #ifdef APP-NVUE  
49 - width: 0, // nvue下才这么计算,vue下放到computed中,否则会因为延时造成闪烁  
50 - // #endif  
51 - classes: [], // 类名集合,用于判断是否显示右边和下边框  
52 - };  
53 - },  
54 - mounted() {  
55 - this.init()  
56 - },  
57 - computed: {  
58 - // #ifndef APP-NVUE  
59 - // vue下放到computed中,否则会因为延时造成闪烁  
60 - width() {  
61 - return 100 / Number(this.parentData.col) + '%'  
62 - },  
63 - // #endif  
64 - itemStyle() {  
65 - const style = {  
66 - background: this.bgColor,  
67 - width: this.width  
68 - }  
69 - return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))  
70 - }  
71 - },  
72 - methods: {  
73 - init() {  
74 - // 用于在父组件u-grid的children中被添加入子组件时,  
75 - // 重新计算item的边框  
76 - uni.$on('$uGridItem', () => {  
77 - this.gridItemClasses()  
78 - })  
79 - // 父组件的实例  
80 - this.updateParentData()  
81 - // #ifdef APP-NVUE  
82 - // 获取元素该有的长度,nvue下要延时才准确  
83 - this.$nextTick(function(){  
84 - this.getItemWidth()  
85 - })  
86 - // #endif  
87 - // 发出事件,通知所有的grid-item都重新计算自己的边框  
88 - uni.$emit('$uGridItem')  
89 - this.gridItemClasses()  
90 - },  
91 - // 获取父组件的参数  
92 - updateParentData() {  
93 - // 此方法写在mixin中  
94 - this.getParentData('u-grid');  
95 - },  
96 - clickHandler() {  
97 - let name = this.name  
98 - // 如果没有设置name属性,历遍父组件的children数组,判断当前的元素是否和本实例this相等,找出当前组件的索引  
99 - const children = this.parent?.children  
100 - if(children && this.name === null) {  
101 - name = children.findIndex(child => child === this)  
102 - }  
103 - // 调用父组件方法,发出事件  
104 - this.parent && this.parent.childClick(name)  
105 - this.$emit('click', name)  
106 - },  
107 - async getItemWidth() {  
108 - // 如果是nvue,不能使用百分比,只能使用固定宽度  
109 - let width = 0  
110 - if(this.parent) {  
111 - // 获取父组件宽度后,除以栅格数,得出每个item的宽度  
112 - const parentWidth = await this.getParentWidth()  
113 - width = parentWidth / Number(this.parentData.col) + 'px'  
114 - }  
115 - this.width = width  
116 - },  
117 - // 获取父元素的尺寸  
118 - getParentWidth() {  
119 - // #ifdef APP-NVUE  
120 - // 返回一个promise,让调用者可以用await同步获取  
121 - const dom = uni.requireNativePlugin('dom')  
122 - return new Promise(resolve => {  
123 - // 调用父组件的ref  
124 - dom.getComponentRect(this.parent.$refs['u-grid'], res => {  
125 - resolve(res.size.width)  
126 - })  
127 - })  
128 - // #endif  
129 - },  
130 - gridItemClasses() {  
131 - if(this.parentData.border) {  
132 - const classes = []  
133 - this.parent.children.map((child, index) =>{  
134 - if(this === child) {  
135 - const len = this.parent.children.length  
136 - // 贴近右边屏幕边沿的child,并且最后一个(比如只有横向2个的时候),无需右边框  
137 - if((index + 1) % this.parentData.col !== 0 && index + 1 !== len) {  
138 - classes.push('u-border-right')  
139 - }  
140 - // 总的宫格数量对列数取余的值  
141 - // 如果取余后,值为0,则意味着要将最后一排的宫格,都不需要下边框  
142 - const lessNum = len % this.parentData.col === 0 ? this.parentData.col : len % this.parentData.col  
143 - // 最下面的一排child,无需下边框  
144 - if(index < len - lessNum) {  
145 - classes.push('u-border-bottom')  
146 - }  
147 - }  
148 - })  
149 - // 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效  
150 - // #ifdef MP-ALIPAY || MP-TOUTIAO  
151 - classes = classes.join(' ')  
152 - // #endif  
153 - this.classes = classes  
154 - }  
155 - }  
156 - },  
157 - beforeDestroy() {  
158 - // 移除事件监听,释放性能  
159 - uni.$off('$uGridItem')  
160 - }  
161 - };  
162 -</script>  
163 -  
164 -<style lang="scss" scoped>  
165 - @import "../../libs/css/components.scss";  
166 - $u-grid-item-hover-class-opcatiy:.5 !default;  
167 - $u-grid-item-margin-top:1rpx !default;  
168 - $u-grid-item-border-right-width:0.5px !default;  
169 - $u-grid-item-border-bottom-width:0.5px !default;  
170 - $u-grid-item-border-right-color:$u-border-color !default;  
171 - $u-grid-item-border-bottom-color:$u-border-color !default;  
172 - .u-grid-item {  
173 - align-items: center;  
174 - justify-content: center;  
175 - position: relative;  
176 - flex-direction: column;  
177 - /* #ifndef APP-NVUE */  
178 - box-sizing: border-box;  
179 - display: flex;  
180 - /* #endif */  
181 -  
182 - /* #ifdef MP */  
183 - position: relative;  
184 - float: left;  
185 - /* #endif */  
186 -  
187 - /* #ifdef MP-WEIXIN */  
188 - margin-top:$u-grid-item-margin-top;  
189 - /* #endif */  
190 -  
191 - &--hover-class {  
192 - opacity:$u-grid-item-hover-class-opcatiy;  
193 - }  
194 - }  
195 -  
196 - /* #ifdef APP-NVUE */  
197 - // 由于nvue不支持组件内引入app.vue中再引入的样式,所以需要写在这里  
198 - .u-border-right {  
199 - border-right-width:$u-grid-item-border-right-width;  
200 - border-color: $u-grid-item-border-right-color;  
201 - }  
202 -  
203 - .u-border-bottom {  
204 - border-bottom-width:$u-grid-item-border-bottom-width;  
205 - border-color:$u-grid-item-border-bottom-color;  
206 - }  
207 -  
208 - /* #endif */  
209 -</style>  
1 -export default {  
2 - props: {  
3 - // 分成几列  
4 - col: {  
5 - type: [String, Number],  
6 - default: uni.$u.props.grid.col  
7 - },  
8 - // 是否显示边框  
9 - border: {  
10 - type: Boolean,  
11 - default: uni.$u.props.grid.border  
12 - },  
13 - // 宫格对齐方式,表现为数量少的时候,靠左,居中,还是靠右  
14 - align: {  
15 - type: String,  
16 - default: uni.$u.props.grid.align  
17 - }  
18 - }  
19 -}  
1 -<template>  
2 - <view  
3 - class="u-grid"  
4 - ref='u-grid'  
5 - :style="[gridStyle]"  
6 - >  
7 - <slot />  
8 - </view>  
9 -</template>  
10 -  
11 -<script>  
12 - import props from './props.js';  
13 - /**  
14 - * grid 宫格布局  
15 - * @description 宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。  
16 - * @tutorial https://www.uviewui.com/components/grid.html  
17 - * @property {String | Number} col 宫格的列数(默认 3 )  
18 - * @property {Boolean} border 是否显示宫格的边框(默认 false )  
19 - * @property {String} align 宫格对齐方式,表现为数量少的时候,靠左,居中,还是靠右 (默认 'left' )  
20 - * @property {Object} customStyle 定义需要用到的外部样式  
21 - * @event {Function} click 点击宫格触发  
22 - * @example <u-grid :col="3" @click="click"></u-grid>  
23 - */  
24 - export default {  
25 - name: 'u-grid',  
26 - mixins: [uni.$u.mpMixin, uni.$u.mixin,props],  
27 - data() {  
28 - return {  
29 - index: 0,  
30 - width: 0  
31 - }  
32 - },  
33 - watch: {  
34 - // 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件  
35 - parentData() {  
36 - if (this.children.length) {  
37 - this.children.map(child => {  
38 - // 判断子组件(u-radio)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)  
39 - typeof(child.updateParentData) == 'function' && child.updateParentData();  
40 - })  
41 - }  
42 - },  
43 - },  
44 - created() {  
45 - // 如果将children定义在data中,在微信小程序会造成循环引用而报错  
46 - this.children = []  
47 - },  
48 - computed: {  
49 - // 计算父组件的值是否发生变化  
50 - parentData() {  
51 - return [this.hoverClass, this.col, this.size, this.border];  
52 - },  
53 - // 宫格对齐方式  
54 - gridStyle() {  
55 - let style = {};  
56 - switch (this.align) {  
57 - case 'left':  
58 - style.justifyContent = 'flex-start';  
59 - break;  
60 - case 'center':  
61 - style.justifyContent = 'center';  
62 - break;  
63 - case 'right':  
64 - style.justifyContent = 'flex-end';  
65 - break;  
66 - default:  
67 - style.justifyContent = 'flex-start';  
68 - };  
69 - return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle));  
70 - }  
71 - },  
72 - methods: {  
73 - // 此方法由u-grid-item触发,用于在u-grid发出事件  
74 - childClick(name) {  
75 - this.$emit('click', name)  
76 - }  
77 - }  
78 - };  
79 -</script>  
80 -  
81 -<style lang="scss" scoped>  
82 - @import "../../libs/css/components.scss";  
83 - $u-grid-width:100% !default;  
84 - .u-grid {  
85 - /* #ifdef MP */  
86 - width: $u-grid-width;  
87 - position: relative;  
88 - box-sizing: border-box;  
89 - overflow: hidden;  
90 - display: block;  
91 - /* #endif */  
92 - justify-content: center;  
93 - @include flex;  
94 - flex-wrap: wrap;  
95 - align-items: center;  
96 - }  
97 -</style>  
1 -export default {  
2 - props: {  
3 - // 标题  
4 - title: {  
5 - type: [String, Number],  
6 - default: uni.$u.props.stepsItem.title  
7 - },  
8 - // 描述文本  
9 - desc: {  
10 - type: [String, Number],  
11 - default: uni.$u.props.stepsItem.desc  
12 - },  
13 - // 图标大小  
14 - iconSize: {  
15 - type: [String, Number],  
16 - default: uni.$u.props.stepsItem.iconSize  
17 - },  
18 - // 当前步骤是否处于失败状态  
19 - error: {  
20 - type: Boolean,  
21 - default: uni.$u.props.stepsItem.error  
22 - }  
23 - }  
24 -}  
1 -<template>  
2 - <view class="u-steps-item" ref="u-steps-item" :class="[`u-steps-item--${parentData.direction}`]">  
3 - <view class="u-steps-item__line" v-if="index + 1 < childLength"  
4 - :class="[`u-steps-item__line--${parentData.direction}`]" :style="[lineStyle]"></view>  
5 - <view class="u-steps-item__wrapper"  
6 - :class="[`u-steps-item__wrapper--${parentData.direction}`, parentData.dot && `u-steps-item__wrapper--${parentData.direction}--dot`]">  
7 - <slot name="icon">  
8 - <view class="u-steps-item__wrapper__dot" v-if="parentData.dot" :style="{  
9 - backgroundColor: statusColor  
10 - }">  
11 -  
12 - </view>  
13 - <view class="u-steps-item__wrapper__icon" v-else-if="parentData.activeIcon || parentData.inactiveIcon">  
14 - <u-icon :name="index <= parentData.current ? parentData.activeIcon : parentData.inactiveIcon"  
15 - :size="iconSize"  
16 - :color="index <= parentData.current ? parentData.activeColor : parentData.inactiveColor">  
17 - </u-icon>  
18 - </view>  
19 - <view v-else :style="{  
20 - backgroundColor: statusClass === 'process' ? parentData.activeColor : 'transparent',  
21 - borderColor: statusColor  
22 - }" class="u-steps-item__wrapper__circle">  
23 - <text v-if="statusClass === 'process' || statusClass === 'wait'"  
24 - class="u-steps-item__wrapper__circle__text" :style="{  
25 - color: index == parentData.current ? '#ffffff' : parentData.inactiveColor  
26 - }">{{ index + 1}}</text>  
27 - <u-icon v-else :color="statusClass === 'error' ? 'error' : parentData.activeColor" size="12"  
28 - :name="statusClass === 'error' ? 'close' : 'checkmark'"></u-icon>  
29 - </view>  
30 - </slot>  
31 - </view>  
32 - <view class="u-steps-item__content" :class="[`u-steps-item__content--${parentData.direction}`]"  
33 - :style="[contentStyle]">  
34 - <u--text :text="title" :type="parentData.current == index ? 'main' : 'content'" lineHeight="20px"  
35 - :size="parentData.current == index ? 14 : 13"></u--text>  
36 - <slot name="desc">  
37 - <u--text :text="desc" type="tips" size="12"></u--text>  
38 - </slot>  
39 - </view>  
40 - <!-- <view  
41 - class="u-steps-item__line"  
42 - v-if="showLine && parentData.direction === 'column'"  
43 - :class="[`u-steps-item__line--${parentData.direction}`]"  
44 - :style="[lineStyle]"  
45 - ></view> -->  
46 - </view>  
47 -</template>  
48 -  
49 -<script>  
50 - import props from './props.js';  
51 - // #ifdef APP-NVUE  
52 - const dom = uni.requireNativePlugin('dom')  
53 - // #endif  
54 - /**  
55 - * StepsItem 步骤条的子组件  
56 - * @description 本组件需要和u-steps配合使用  
57 - * @tutorial https://uviewui.com/components/steps.html  
58 - * @property {String} title 标题文字  
59 - * @property {String} current 描述文本  
60 - * @property {String | Number} iconSize 图标大小 (默认 17 )  
61 - * @property {Boolean} error 当前步骤是否处于失败状态 (默认 false )  
62 - * @example <u-steps current="0"><u-steps-item title="已出库" desc="10:35" ></u-steps-item></u-steps>  
63 - */  
64 - export default {  
65 - name: 'u-steps-item',  
66 - mixins: [uni.$u.mpMixin, uni.$u.mixin, props],  
67 - data() {  
68 - return {  
69 - index: 0,  
70 - childLength: 0,  
71 - showLine: false,  
72 - size: {  
73 - height: 0,  
74 - width: 0  
75 - },  
76 - parentData: {  
77 - direction: 'row',  
78 - current: 0,  
79 - activeColor: '',  
80 - inactiveColor: '',  
81 - activeIcon: '',  
82 - inactiveIcon: '',  
83 - dot: false  
84 - }  
85 - }  
86 - },  
87 - watch: {  
88 - 'parentData'(newValue, oldValue) {  
89 - }  
90 - },  
91 - created() {  
92 - this.init()  
93 - },  
94 - computed: {  
95 - lineStyle() {  
96 - const style = {}  
97 - if (this.parentData.direction === 'row') {  
98 - style.width = this.size.width + 'px'  
99 - style.left = this.size.width / 2 + 'px'  
100 - } else {  
101 - style.height = this.size.height + 'px'  
102 - // style.top = this.size.height / 2 + 'px'  
103 - }  
104 - style.backgroundColor = this.parent.children?.[this.index + 1]?.error ? uni.$u.color.error : this.index <  
105 - this  
106 - .parentData  
107 - .current ? this.parentData.activeColor : this.parentData.inactiveColor  
108 - return style  
109 - },  
110 - statusClass() {  
111 - const {  
112 - index,  
113 - error  
114 - } = this  
115 - const {  
116 - current  
117 - } = this.parentData  
118 - if (current == index) {  
119 - return error === true ? 'error' : 'process'  
120 - } else if (error) {  
121 - return 'error'  
122 - } else if (current > index) {  
123 - return 'finish'  
124 - } else {  
125 - return 'wait'  
126 - }  
127 - },  
128 - statusColor() {  
129 - let color = ''  
130 - switch (this.statusClass) {  
131 - case 'finish':  
132 - color = this.parentData.activeColor  
133 - break  
134 - case 'error':  
135 - color = uni.$u.color.error  
136 - break  
137 - case 'process':  
138 - color = this.parentData.dot ? this.parentData.activeColor : 'transparent'  
139 - break  
140 - default:  
141 - color = this.parentData.inactiveColor  
142 - break  
143 - }  
144 - return color  
145 - },  
146 - contentStyle() {  
147 - const style = {}  
148 - if (this.parentData.direction === 'column') {  
149 - style.marginLeft = this.parentData.dot ? '2px' : '6px'  
150 - style.marginTop = this.parentData.dot ? '0px' : '6px'  
151 - } else {  
152 - style.marginTop = this.parentData.dot ? '2px' : '6px'  
153 - style.marginLeft = this.parentData.dot ? '2px' : '6px'  
154 - }  
155 -  
156 - return style  
157 - }  
158 - },  
159 - mounted() {  
160 - this.parent && this.parent.updateFromChild()  
161 - uni.$u.sleep().then(() => {  
162 - this.getStepsItemRect()  
163 - })  
164 - },  
165 - methods: {  
166 - init() {  
167 - // 初始化数据  
168 - this.updateParentData()  
169 - if (!this.parent) {  
170 - return uni.$u.error('u-steps-item必须要搭配u-steps组件使用')  
171 - }  
172 - this.index = this.parent.children.indexOf(this)  
173 - this.childLength = this.parent.children.length  
174 - },  
175 - updateParentData() {  
176 - // 此方法在mixin中  
177 - this.getParentData('u-steps')  
178 - },  
179 - // 父组件数据发生变化  
180 - updateFromParent() {  
181 - this.init()  
182 - },  
183 - // 获取组件的尺寸,用于设置横线的位置  
184 - getStepsItemRect() {  
185 - // #ifndef APP-NVUE  
186 - this.$uGetRect('.u-steps-item').then(size => {  
187 - this.size = size  
188 - })  
189 - // #endif  
190 -  
191 - // #ifdef APP-NVUE  
192 - dom.getComponentRect(this.$refs['u-steps-item'], res => {  
193 - const {  
194 - size  
195 - } = res  
196 - this.size = size  
197 - })  
198 - // #endif  
199 - }  
200 - }  
201 - }  
202 -</script>  
203 -  
204 -<style lang="scss" scoped>  
205 - @import "../../libs/css/components.scss";  
206 -  
207 - .u-steps-item {  
208 - flex: 1;  
209 - @include flex;  
210 -  
211 - &--row {  
212 - flex-direction: column;  
213 - align-items: center;  
214 - position: relative;  
215 - }  
216 -  
217 - &--column {  
218 - position: relative;  
219 - flex-direction: row;  
220 - justify-content: flex-start;  
221 - padding-bottom: 5px;  
222 - }  
223 -  
224 - &__wrapper {  
225 - @include flex;  
226 - justify-content: center;  
227 - align-items: center;  
228 - position: relative;  
229 - background-color: #fff;  
230 -  
231 - &--column {  
232 - width: 20px;  
233 - height: 32px;  
234 -  
235 - &--dot {  
236 - height: 20px;  
237 - width: 20px;  
238 - }  
239 - }  
240 -  
241 - &--row {  
242 - width: 32px;  
243 - height: 20px;  
244 -  
245 - &--dot {  
246 - width: 20px;  
247 - height: 20px;  
248 - }  
249 - }  
250 -  
251 - &__circle {  
252 - width: 20px;  
253 - height: 20px;  
254 - /* #ifndef APP-NVUE */  
255 - box-sizing: border-box;  
256 - flex-shrink: 0;  
257 - /* #endif */  
258 - border-radius: 100px;  
259 - border-width: 1px;  
260 - border-color: $u-tips-color;  
261 - border-style: solid;  
262 - @include flex(row);  
263 - align-items: center;  
264 - justify-content: center;  
265 - transition: background-color 0.3s;  
266 -  
267 - &__text {  
268 - color: $u-tips-color;  
269 - font-size: 11px;  
270 - @include flex(row);  
271 - align-items: center;  
272 - justify-content: center;  
273 - text-align: center;  
274 - line-height: 11px;  
275 - }  
276 - }  
277 -  
278 - &__dot {  
279 - width: 10px;  
280 - height: 10px;  
281 - border-radius: 100px;  
282 - background-color: $u-content-color;  
283 - }  
284 - }  
285 -  
286 - &__content {  
287 - @include flex;  
288 - flex: 1;  
289 -  
290 - &--row {  
291 - flex-direction: column;  
292 - align-items: center;  
293 - }  
294 -  
295 - &--column {  
296 - flex-direction: column;  
297 - margin-left: 6px;  
298 - }  
299 - }  
300 -  
301 - &__line {  
302 - position: absolute;  
303 - background: $u-tips-color;  
304 -  
305 - &--row {  
306 - top: 10px;  
307 - height: 1px;  
308 - }  
309 -  
310 - &--column {  
311 - width: 1px;  
312 - left: 10px;  
313 - }  
314 - }  
315 - }  
316 -</style>  
1 -export default {  
2 - props: {  
3 - // 排列方向  
4 - direction: {  
5 - type: String,  
6 - default: uni.$u.props.steps.direction  
7 - },  
8 - // 设置第几个步骤  
9 - current: {  
10 - type: [String, Number],  
11 - default: uni.$u.props.steps.current  
12 - },  
13 - // 激活状态颜色  
14 - activeColor: {  
15 - type: String,  
16 - default: uni.$u.props.steps.activeColor  
17 - },  
18 - // 未激活状态颜色  
19 - inactiveColor: {  
20 - type: String,  
21 - default: uni.$u.props.steps.inactiveColor  
22 - },  
23 - // 激活状态的图标  
24 - activeIcon: {  
25 - type: String,  
26 - default: uni.$u.props.steps.activeIcon  
27 - },  
28 - // 未激活状态图标  
29 - inactiveIcon: {  
30 - type: String,  
31 - default: uni.$u.props.steps.inactiveIcon  
32 - },  
33 - // 是否显示点类型  
34 - dot: {  
35 - type: Boolean,  
36 - default: uni.$u.props.steps.dot  
37 - }  
38 - }  
39 -}  
1 -<template>  
2 - <view  
3 - class="u-steps"  
4 - :class="[`u-steps--${direction}`]"  
5 - >  
6 - <slot></slot>  
7 - </view>  
8 -</template>  
9 -  
10 -<script>  
11 - import props from './props.js';  
12 - /**  
13 - * Steps 步骤条  
14 - * @description 该组件一般用于完成一个任务要分几个步骤,标识目前处于第几步的场景。  
15 - * @tutorial https://uviewui.com/components/steps.html  
16 - * @property {String} direction row-横向,column-竖向 (默认 'row' )  
17 - * @property {String | Number} current 设置当前处于第几步 (默认 0 )  
18 - * @property {String} activeColor 激活状态颜色 (默认 '#3c9cff' )  
19 - * @property {String} inactiveColor 未激活状态颜色 (默认 '#969799' )  
20 - * @property {String} activeIcon 激活状态的图标  
21 - * @property {String} inactiveIcon 未激活状态图标  
22 - * @property {Boolean} dot 是否显示点类型 (默认 false )  
23 - * @example <u-steps current="0"><u-steps-item title="已出库" desc="10:35" ></u-steps-item></u-steps>  
24 - */  
25 - export default {  
26 - name: 'u-steps',  
27 - mixins: [uni.$u.mpMixin, uni.$u.mixin, props],  
28 - data() {  
29 - return {  
30 - }  
31 - },  
32 - watch: {  
33 - children() {  
34 - this.updateChildData()  
35 - },  
36 - parentData() {  
37 - this.updateChildData()  
38 - }  
39 - },  
40 - computed: {  
41 - // 监听参数的变化,通过watch中,手动去更新子组件的数据,否则子组件不会自动变化  
42 - parentData() {  
43 - return [this.current, this.direction, this.activeColor, this.inactiveColor, this.activeIcon, this.inactiveIcon, this.dot]  
44 - }  
45 - },  
46 - methods: {  
47 - // 更新子组件的数据  
48 - updateChildData() {  
49 - this.children.map(child => {  
50 - // 先判断子组件是否存在对应的方法  
51 - uni.$u.test.func((child || {}).updateFromParent()) && child.updateFromParent()  
52 - })  
53 - },  
54 - // 接受子组件的通知,去修改其他子组件的数据  
55 - updateFromChild() {  
56 - this.updateChildData()  
57 - }  
58 - },  
59 - created() {  
60 - this.children = []  
61 - }  
62 - }  
63 -</script>  
64 -  
65 -<style lang="scss" scoped>  
66 - @import "../../libs/css/components.scss";  
67 -  
68 - .u-steps {  
69 - @include flex;  
70 -  
71 - &--column {  
72 - flex-direction: column  
73 - }  
74 -  
75 - &--row {  
76 - flex-direction: row;  
77 - flex: 1;  
78 - }  
79 - }  
80 -</style>  
1 -/**  
2 - * 此为wxs模块,只支持APP-VUE,微信和QQ小程序以及H5平台  
3 - * wxs内部不支持es6语法,变量只能使用var定义,无法使用解构,箭头函数等特性  
4 - */  
5 -  
6 -// 开始触摸  
7 -function touchstart(event, ownerInstance) {  
8 - // 触发事件的组件的ComponentDescriptor实例  
9 - var instance = event.instance  
10 - // wxs内的局部变量快照,此快照是属于整个组件的,在touchstart和touchmove事件中都能获取到相同的结果  
11 - var state = instance.getState()  
12 - if (state.disable) return  
13 - var touches = event.touches  
14 - // 如果进行的是多指触控,不允许进行操作  
15 - if (touches && touches.length > 1) return  
16 - // 标识当前为滑动中状态  
17 - state.moving = true  
18 - // 记录触摸开始点的坐标值  
19 - state.startX = touches[0].pageX  
20 - state.startY = touches[0].pageY  
21 -}  
22 -  
23 -// 触摸滑动  
24 -function touchmove(event, ownerInstance) {  
25 - // 触发事件的组件的ComponentDescriptor实例  
26 - var instance = event.instance  
27 - // wxs内的局部变量快照  
28 - var state = instance.getState()  
29 - if (state.disabled || !state.moving) return  
30 -  
31 - var touches = event.touches  
32 - var pageX = touches[0].pageX  
33 - var pageY = touches[0].pageY  
34 - var moveX = pageX - state.startX  
35 - var moveY = pageY - state.startY  
36 - var buttonsWidth = state.buttonsWidth  
37 -  
38 - // 移动的X轴距离大于Y轴距离,也即终点与起点位置连线,与X轴夹角小于45度时,禁止页面滚动  
39 - if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) {  
40 - event.preventDefault()  
41 - event.stopPropagation()  
42 - }  
43 - // 如果移动的X轴距离小于Y轴距离,也即终点位置与起点位置连线,与Y轴夹角小于45度时,认为是页面上下滑动,而不是左右滑动单元格  
44 - if (Math.abs(moveX) < Math.abs(moveY)) return  
45 -  
46 - // 限制右滑的距离,不允许内容部分往右偏移,右滑会导致X轴偏移值大于0,以此做判断  
47 - // 此处不能直接return,因为滑动过程中会缺失某些关键点坐标,会导致错乱,最好的办法就是  
48 - // 在超出后,设置为0  
49 - if (state.status === 'open') {  
50 - // 在开启状态下,向左滑动,需忽略  
51 - if (moveX < 0) moveX = 0  
52 - // 想要收起菜单,最大能移动的距离为按钮的总宽度  
53 - if (moveX > buttonsWidth) moveX = buttonsWidth  
54 - // 如果是已经打开了的状态,向左滑动时,移动收起菜单  
55 - moveSwipeAction(-buttonsWidth + moveX, instance, ownerInstance)  
56 - } else {  
57 - // 关闭状态下,右滑动需忽略  
58 - if (moveX > 0) moveX = 0  
59 - // 滑动的距离不允许超过所有按钮的总宽度,此时只能是左滑,最终设置按钮的总宽度,同时为负数  
60 - if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth  
61 - // 只要是在滑过程中,就不断移动菜单的内容部分,从而使隐藏的菜单显示出来  
62 - moveSwipeAction(moveX, instance, ownerInstance)  
63 - }  
64 -}  
65 -  
66 -// 触摸结束  
67 -function touchend(event, ownerInstance) {  
68 - // 触发事件的组件的ComponentDescriptor实例  
69 - var instance = event.instance  
70 - // wxs内的局部变量快照  
71 - var state = instance.getState()  
72 - if (!state.moving || state.disabled) return  
73 - var touches = event.changedTouches ? event.changedTouches[0] : {}  
74 - var pageX = touches.pageX  
75 - var pageY = touches.pageY  
76 - var moveX = pageX - state.startX  
77 - if (state.status === 'open') {  
78 - // 在展开的状态下,继续左滑,无需操作  
79 - if (moveX < 0) return  
80 - // 在开启状态下,点击一下内容区域,moveX为0,也即没有进行移动,这时执行收起菜单逻辑  
81 - if (moveX === 0) {  
82 - return closeSwipeAction(instance, ownerInstance)  
83 - }  
84 - // 在开启状态下,滑动距离小于阈值,则默认为不关闭,同时恢复原来的打开状态  
85 - if (Math.abs(moveX) < state.threshold) {  
86 - openSwipeAction(instance, ownerInstance)  
87 - } else {  
88 - // 如果滑动距离大于阈值,则执行收起逻辑  
89 - closeSwipeAction(instance, ownerInstance)  
90 - }  
91 - } else {  
92 - // 在关闭的状态下,右滑,无需操作  
93 - if (moveX > 0) return  
94 - // 理由同上  
95 - if (Math.abs(moveX) < state.threshold) {  
96 - closeSwipeAction(instance, ownerInstance)  
97 - } else {  
98 - openSwipeAction(instance, ownerInstance)  
99 - }  
100 - }  
101 -}  
102 -  
103 -// 获取过渡时间  
104 -function getDuration(value) {  
105 - if (value.toString().indexOf('s') >= 0) return value  
106 - return value > 30 ? value + 'ms' : value + 's'  
107 -}  
108 -  
109 -// 滑动结束时判断滑动的方向  
110 -function getMoveDirection(instance, ownerInstance) {  
111 - var state = instance.getState()  
112 -}  
113 -  
114 -// 移动滑动选择器内容区域,同时显示出其隐藏的菜单  
115 -function moveSwipeAction(moveX, instance, ownerInstance) {  
116 - var state = instance.getState()  
117 - // 获取所有按钮的实例,需要通过它去设置按钮的位移  
118 - var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button')  
119 - var len = buttons.length  
120 - var previewButtonsMoveX = 0  
121 -  
122 - // 设置菜单内容部分的偏移  
123 - instance.requestAnimationFrame(function() {  
124 - instance.setStyle({  
125 - // 设置translateX的值  
126 - 'transition': 'none',  
127 - transform: 'translateX(' + moveX + 'px)',  
128 - '-webkit-transform': 'translateX(' + moveX + 'px)'  
129 - })  
130 - // 折叠按钮动画  
131 - for (var i = len - 1; i >= 0; i--) {  
132 - // 通过比例,得出元素自身该移动的距离  
133 - var translateX = state.buttons[i].width / state.buttonsWidth * moveX  
134 - // 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和  
135 - var realTranslateX = translateX + previewButtonsMoveX  
136 - buttons[i].setStyle({  
137 - // 在移动期间,不能使用过渡效果,否则会造成卡顿,本质原因是每次移动一点,就要花一定时间去过渡这个过程  
138 - 'transition': 'none',  
139 - 'transform': 'translateX(' + realTranslateX + 'px)',  
140 - '-webkit-transform': 'translateX(' + realTranslateX + 'px)'  
141 - })  
142 - // 记录本按钮之前的所有按钮的移动距离之和  
143 - previewButtonsMoveX += translateX  
144 - }  
145 - })  
146 -}  
147 -  
148 -// 一次性展开滑动菜单  
149 -function openSwipeAction(instance, ownerInstance) {  
150 - var state = instance.getState()  
151 - // 获取所有按钮的实例,需要通过它去设置按钮的位移  
152 - var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button')  
153 - var len = buttons.length  
154 - // 处理duration单位问题  
155 - const duration = getDuration(state.duration)  
156 - // 展开过程中,是向左移动,所以X的偏移应该为负值  
157 - var buttonsWidth = -state.buttonsWidth  
158 - var previewButtonsMoveX = 0  
159 - instance.requestAnimationFrame(function() {  
160 - // 设置菜单主体内容  
161 - instance.setStyle({  
162 - 'transition': 'transform ' + duration,  
163 - 'transform': 'translateX(' + buttonsWidth + 'px)',  
164 - '-webkit-transform': 'translateX(' + buttonsWidth + 'px)',  
165 - })  
166 - // 设置各个隐藏的按钮为展开的状态  
167 - for (var i = len - 1; i >= 0; i--) {  
168 - // 通过比例,得出元素自身该移动的距离  
169 - var translateX = state.buttons[i].width / state.buttonsWidth * buttonsWidth  
170 - // 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和  
171 - var realTranslateX = translateX + previewButtonsMoveX  
172 - buttons[i].setStyle({  
173 - // 在移动期间,需要加上动画效果  
174 - 'transition': 'transform ' + duration,  
175 - 'transform': 'translateX(' + realTranslateX + 'px)',  
176 - '-webkit-transform': 'translateX(' + realTranslateX + 'px)'  
177 - })  
178 - // 记录本按钮之前的所有按钮的移动距离之和  
179 - previewButtonsMoveX += translateX  
180 - }  
181 - })  
182 - setStatus('open', instance)  
183 -}  
184 -  
185 -// 标记菜单的当前状态,open-已经打开,close-已经关闭  
186 -function setStatus(status, instance) {  
187 - var state = instance.getState()  
188 - state.status = status  
189 -}  
190 -  
191 -// 一次性收起滑动菜单  
192 -function closeSwipeAction(instance, ownerInstance) {  
193 - var state = instance.getState()  
194 - // 获取所有按钮的实例,需要通过它去设置按钮的位移  
195 - var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button')  
196 - var len = buttons.length  
197 - // 处理duration单位问题  
198 - const duration = getDuration(state.duration)  
199 - instance.requestAnimationFrame(function() {  
200 - // 设置菜单主体内容  
201 - instance.setStyle({  
202 - 'transition': 'transform ' + duration,  
203 - 'transform': 'translateX(0px)',  
204 - '-webkit-transform': 'translateX(0px)'  
205 - })  
206 - // 设置各个隐藏的按钮为收起的状态  
207 - for (var i = len - 1; i >= 0; i--) {  
208 - buttons[i].setStyle({  
209 - 'transition': 'transform ' + duration,  
210 - 'transform': 'translateX(0px)',  
211 - '-webkit-transform': 'translateX(0px)'  
212 - })  
213 - }  
214 - })  
215 - setStatus('close', instance)  
216 -}  
217 -  
218 -// show的状态发生变化  
219 -function showChange(newValue, oldValue, ownerInstance, instance) {  
220 - var state = instance.getState()  
221 - if (state.disabled) return  
222 - // 打开或关闭单元格  
223 - if (newValue) {  
224 - openSwipeAction(instance, ownerInstance)  
225 - } else {  
226 - closeSwipeAction(instance, ownerInstance)  
227 - }  
228 -}  
229 -  
230 -// 菜单尺寸发生变化  
231 -function sizeChange(newValue, oldValue, ownerInstance, instance) {  
232 - // wxs内的局部变量快照  
233 - var state = instance.getState()  
234 - state.disabled = newValue.disabled  
235 - state.duration = newValue.duration  
236 - state.show = newValue.show  
237 - state.threshold = newValue.threshold  
238 - state.buttons = newValue.buttons  
239 -  
240 - var len = state.buttons.length  
241 - if (len) {  
242 - var buttonsWidth = 0  
243 - var buttons = newValue.buttons  
244 - for (var i = 0; i < len; i++) {  
245 - buttonsWidth += buttons[i].width  
246 - }  
247 - }  
248 - state.buttonsWidth = buttonsWidth  
249 -}  
250 -  
251 -module.exports = {  
252 - touchstart: touchstart,  
253 - touchmove: touchmove,  
254 - touchend: touchend,  
255 - sizeChange: sizeChange  
256 -}  
1 -/**  
2 - * 此为wxs模块,只支持APP-VUE,微信和QQ小程序以及H5平台  
3 - * wxs内部不支持es6语法,变量只能使用var定义,无法使用解构,箭头函数等特性  
4 - */  
5 -  
6 -// 开始触摸  
7 -function touchstart(event, ownerInstance) {  
8 - // 触发事件的组件的ComponentDescriptor实例  
9 - var instance = event.instance  
10 - // wxs内的局部变量快照,此快照是属于整个组件的,在touchstart和touchmove事件中都能获取到相同的结果  
11 - var state = instance.getState()  
12 - if (state.disabled) return  
13 - var touches = event.touches  
14 - // 如果进行的是多指触控,不允许进行操作  
15 - if (touches && touches.length > 1) return  
16 - // 标识当前为滑动中状态  
17 - state.moving = true  
18 - // 记录触摸开始点的坐标值  
19 - state.startX = touches[0].pageX  
20 - state.startY = touches[0].pageY  
21 -  
22 - ownerInstance.callMethod('closeOther')  
23 -}  
24 -  
25 -// 触摸滑动  
26 -function touchmove(event, ownerInstance) {  
27 - // 触发事件的组件的ComponentDescriptor实例  
28 - var instance = event.instance  
29 - // wxs内的局部变量快照  
30 - var state = instance.getState()  
31 - if (state.disabled || !state.moving) return  
32 - var touches = event.touches  
33 - var pageX = touches[0].pageX  
34 - var pageY = touches[0].pageY  
35 - var moveX = pageX - state.startX  
36 - var moveY = pageY - state.startY  
37 - var buttonsWidth = state.buttonsWidth  
38 -  
39 - // 移动的X轴距离大于Y轴距离,也即终点与起点位置连线,与X轴夹角小于45度时,禁止页面滚动  
40 - if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) {  
41 - event.preventDefault && event.preventDefault()  
42 - event.stopPropagation && event.stopPropagation()  
43 - }  
44 - // 如果移动的X轴距离小于Y轴距离,也即终点位置与起点位置连线,与Y轴夹角小于45度时,认为是页面上下滑动,而不是左右滑动单元格  
45 - if (Math.abs(moveX) < Math.abs(moveY)) return  
46 -  
47 - // 限制右滑的距离,不允许内容部分往右偏移,右滑会导致X轴偏移值大于0,以此做判断  
48 - // 此处不能直接return,因为滑动过程中会缺失某些关键点坐标,会导致错乱,最好的办法就是  
49 - // 在超出后,设置为0  
50 - if (state.status === 'open') {  
51 - // 在开启状态下,向左滑动,需忽略  
52 - if (moveX < 0) moveX = 0  
53 - // 想要收起菜单,最大能移动的距离为按钮的总宽度  
54 - if (moveX > buttonsWidth) moveX = buttonsWidth  
55 - // 如果是已经打开了的状态,向左滑动时,移动收起菜单  
56 - moveSwipeAction(-buttonsWidth + moveX, instance, ownerInstance)  
57 - } else {  
58 - // 关闭状态下,右滑动需忽略  
59 - if (moveX > 0) moveX = 0  
60 - // 滑动的距离不允许超过所有按钮的总宽度,此时只能是左滑,最终设置按钮的总宽度,同时为负数  
61 - if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth  
62 - // 只要是在滑过程中,就不断移动单元格内容部分,从而使隐藏的菜单显示出来  
63 - moveSwipeAction(moveX, instance, ownerInstance)  
64 - }  
65 -}  
66 -  
67 -// 触摸结束  
68 -function touchend(event, ownerInstance) {  
69 - // 触发事件的组件的ComponentDescriptor实例  
70 - var instance = event.instance  
71 - // wxs内的局部变量快照  
72 - var state = instance.getState()  
73 - if (!state.moving || state.disabled) return  
74 - var touches = event.changedTouches ? event.changedTouches[0] : {}  
75 - var pageX = touches.pageX  
76 - var pageY = touches.pageY  
77 - var moveX = pageX - state.startX  
78 - if (state.status === 'open') {  
79 - // 在展开的状态下,继续左滑,无需操作  
80 - if (moveX < 0) return  
81 - // 在开启状态下,点击一下内容区域,moveX为0,也即没有进行移动,这时执行收起菜单逻辑  
82 - if (moveX === 0) {  
83 - return closeSwipeAction(instance, ownerInstance)  
84 - }  
85 - // 在开启状态下,滑动距离小于阈值,则默认为不关闭,同时恢复原来的打开状态  
86 - if (Math.abs(moveX) < state.threshold) {  
87 - openSwipeAction(instance, ownerInstance)  
88 - } else {  
89 - // 如果滑动距离大于阈值,则执行收起逻辑  
90 - closeSwipeAction(instance, ownerInstance)  
91 - }  
92 - } else {  
93 - // 在关闭的状态下,右滑,无需操作  
94 - if (moveX > 0) return  
95 - // 理由同上  
96 - if (Math.abs(moveX) < state.threshold) {  
97 - closeSwipeAction(instance, ownerInstance)  
98 - } else {  
99 - openSwipeAction(instance, ownerInstance)  
100 - }  
101 - }  
102 -}  
103 -  
104 -// 获取过渡时间  
105 -function getDuration(value) {  
106 - if (value.toString().indexOf('s') >= 0) return value  
107 - return value > 30 ? value + 'ms' : value + 's'  
108 -}  
109 -  
110 -// 滑动结束时判断滑动的方向  
111 -function getMoveDirection(instance, ownerInstance) {  
112 - var state = instance.getState()  
113 -}  
114 -  
115 -// 移动滑动选择器内容区域,同时显示出其隐藏的菜单  
116 -function moveSwipeAction(moveX, instance, ownerInstance) {  
117 - var state = instance.getState()  
118 - // 获取所有按钮的实例,需要通过它去设置按钮的位移  
119 - var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button')  
120 -  
121 - // 设置菜单内容部分的偏移  
122 - instance.requestAnimationFrame(function() {  
123 - instance.setStyle({  
124 - // 设置translateX的值  
125 - 'transition': 'none',  
126 - transform: 'translateX(' + moveX + 'px)',  
127 - '-webkit-transform': 'translateX(' + moveX + 'px)'  
128 - })  
129 - })  
130 -}  
131 -  
132 -// 一次性展开滑动菜单  
133 -function openSwipeAction(instance, ownerInstance) {  
134 - var state = instance.getState()  
135 - // 获取所有按钮的实例,需要通过它去设置按钮的位移  
136 - var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button')  
137 - // 处理duration单位问题  
138 - var duration = getDuration(state.duration)  
139 - // 展开过程中,是向左移动,所以X的偏移应该为负值  
140 - var buttonsWidth = -state.buttonsWidth  
141 - instance.requestAnimationFrame(function() {  
142 - // 设置菜单主体内容  
143 - instance.setStyle({  
144 - 'transition': 'transform ' + duration,  
145 - 'transform': 'translateX(' + buttonsWidth + 'px)',  
146 - '-webkit-transform': 'translateX(' + buttonsWidth + 'px)',  
147 - })  
148 - })  
149 - setStatus('open', instance, ownerInstance)  
150 -}  
151 -  
152 -// 标记菜单的当前状态,open-已经打开,close-已经关闭  
153 -function setStatus(status, instance, ownerInstance) {  
154 - var state = instance.getState()  
155 - state.status = status  
156 - ownerInstance.callMethod('setState', status)  
157 -}  
158 -  
159 -// 一次性收起滑动菜单  
160 -function closeSwipeAction(instance, ownerInstance) {  
161 - var state = instance.getState()  
162 - // 获取所有按钮的实例,需要通过它去设置按钮的位移  
163 - var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button')  
164 - var len = buttons.length  
165 - // 处理duration单位问题  
166 - var duration = getDuration(state.duration)  
167 - instance.requestAnimationFrame(function() {  
168 - // 设置菜单主体内容  
169 - instance.setStyle({  
170 - 'transition': 'transform ' + duration,  
171 - 'transform': 'translateX(0px)',  
172 - '-webkit-transform': 'translateX(0px)'  
173 - })  
174 - // 设置各个隐藏的按钮为收起的状态  
175 - for (var i = len - 1; i >= 0; i--) {  
176 - buttons[i].setStyle({  
177 - 'transition': 'transform ' + duration,  
178 - 'transform': 'translateX(0px)',  
179 - '-webkit-transform': 'translateX(0px)'  
180 - })  
181 - }  
182 - })  
183 - setStatus('close', instance, ownerInstance)  
184 -}  
185 -  
186 -// status的状态发生变化  
187 -function statusChange(newValue, oldValue, ownerInstance, instance) {  
188 - var state = instance.getState()  
189 - if (state.disabled) return  
190 - // 打开或关闭单元格  
191 - if (newValue === 'close' && state.status === 'open') {  
192 - closeSwipeAction(instance, ownerInstance)  
193 - } else if(newValue === 'open' && state.status === 'close') {  
194 - openSwipeAction(instance, ownerInstance)  
195 - }  
196 -}  
197 -  
198 -// 菜单尺寸发生变化  
199 -function sizeChange(newValue, oldValue, ownerInstance, instance) {  
200 - // wxs内的局部变量快照  
201 - var state = instance.getState()  
202 - state.disabled = newValue.disabled  
203 - state.duration = newValue.duration  
204 - state.show = newValue.show  
205 - state.threshold = newValue.threshold  
206 - state.buttons = newValue.buttons  
207 -  
208 - if (state.buttons) {  
209 - var len = state.buttons.length  
210 - var buttonsWidth = 0  
211 - var buttons = newValue.buttons  
212 - for (var i = 0; i < len; i++) {  
213 - buttonsWidth += buttons[i].width  
214 - }  
215 - }  
216 - state.buttonsWidth = buttonsWidth  
217 -}  
218 -  
219 -module.exports = {  
220 - touchstart: touchstart,  
221 - touchmove: touchmove,  
222 - touchend: touchend,  
223 - sizeChange: sizeChange,  
224 - statusChange: statusChange  
225 -}