Commit 3e2740174e6ac062cd77efe3f41de12ba486c7ca

Authored by xp.Huang
2 parents 62a3bd84 2b59eb06

Merge branch 'fix/app-view-configuration' into 'main_dev'

fix: 修复小程序无法访问重构后的组态

See merge request yunteng/thingskit-app!118
1 -<template>  
2 - <view class="status-page">  
3 - <view style="margin-left:15rpx;background-color: #f8f9fa;position:fixed;top:0rpx;z-index: 99999;">  
4 - <view style="height:35rpx;background-color: #f8f9fa;"></view>  
5 - <view class="u-flex search-top">  
6 - <view class="search-main">  
7 - <u--input @change="inputChanged" prefixIcon="search" placeholder="请输入组态名称" border="surround"  
8 - shape="circle"></u--input>  
9 - </view>  
10 - </view>  
11 - </view>  
12 - <view style="height:35rpx"></view>  
13 - <!-- 公共组件-每个页面必须引入 -->  
14 - <public-module></public-module>  
15 - <!-- 自带分页组件 -->  
16 - <mescroll-body ref="mescrollRef" :up="upOption" @init="mescrollInit" :down="downOption" @down="downCallback"  
17 - @up="upCallback">  
18 - <view class="configuation-container">  
19 - <view class="configuation-item">  
20 - <view @click="openConfigDetail(item.id)" v-for="(item, index) in list" :key="index" class="item">  
21 - <image class="image" :src="item.icon || defaultConfigImage"></image>  
22 - <text class="name">{{ item.name }}</text>  
23 - </view>  
24 - </view>  
25 - </view>  
26 - <mescroll-empty v-if="!list.length" />  
27 - </mescroll-body>  
28 - <!-- 自带分页组件 -->  
29 - <view style="height: 60rpx;"></view>  
30 - </view>  
31 -</template>  
32 -  
33 -<script>  
34 - import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';  
35 - import api from '@/api/index.js'  
36 -  
37 - export default {  
38 - mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件)  
39 - data() {  
40 - return {  
41 - defaultConfigImage: '../../../static/test.png',  
42 - page: {  
43 - num: 0,  
44 - size: 10  
45 - },  
46 - downOption: {  
47 - auto: true //是否在初始化后,自动执行downCallback; 默认true  
48 - },  
49 - upOption: {  
50 - auto: false // 不自动加载  
51 - },  
52 - list: []  
53 - };  
54 - },  
55 - onLoad() {  
56 - // 隐藏原生的tabbar  
57 - uni.hideTabBar();  
58 - uni.setStorageSync('getConfiguration', {  
59 - isConfiguration: false  
60 - });  
61 - },  
62 - onUnload() {  
63 - uni.setStorageSync('getConfiguration', {  
64 - isConfiguration: false  
65 - });  
66 - uni.removeStorageSync('getConfiguration');  
67 - },  
68 - methods: {  
69 - inputChanged(e) {  
70 - this.page.num = 1;  
71 - this.loadData(1, e);  
72 - },  
73 - openConfigDetail(e) {  
74 - uni.navigateTo({  
75 - url: 'configurationDetail?configId=' + e  
76 - });  
77 - },  
78 - /*下拉刷新的回调 */  
79 - downCallback() {  
80 - //联网加载数据  
81 - this.page.num = 1;  
82 - this.loadData(1);  
83 - },  
84 - /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */  
85 - upCallback() {  
86 - //联网加载数据  
87 - this.page.num += 1;  
88 - this.loadData(this.page.num);  
89 - },  
90 - async loadData(pageNo, organizationV) {  
91 - let httpData = {  
92 - page: pageNo,  
93 - pageSize: 10,  
94 - name: organizationV,  
95 - platform: 'phone'  
96 - };  
97 - const res = await api.homeApi.getConfigurationApi({  
98 - params: httpData,  
99 - custom: {  
100 - load: false  
101 - }  
102 - })  
103 - if (res) {  
104 - uni.stopPullDownRefresh();  
105 - this.mescroll.endByPage(res.items.length, res.total);  
106 - this.cameraTotal = res.total;  
107 - if (pageNo == 1) {  
108 - this.list = res.items;  
109 - } else {  
110 - this.list = this.list.concat(res.items);  
111 - }  
112 - }  
113 - }  
114 - }  
115 - };  
116 -</script>  
117 -  
118 -<style lang="scss" scoped>  
119 - @import '../static/configuration.scss';  
120 -</style> 1 +<template>
  2 + <view class="status-page">
  3 + <view style="margin-left:15rpx;background-color: #f8f9fa;position:fixed;top:0rpx;z-index: 99999;">
  4 + <view style="height:35rpx;background-color: #f8f9fa;"></view>
  5 + <view class="u-flex search-top">
  6 + <view class="search-main">
  7 + <u--input @change="inputChanged" prefixIcon="search" placeholder="请输入组态名称" border="surround"
  8 + shape="circle"></u--input>
  9 + </view>
  10 + </view>
  11 + </view>
  12 + <view style="height:35rpx"></view>
  13 + <!-- 公共组件-每个页面必须引入 -->
  14 + <public-module></public-module>
  15 + <!-- 自带分页组件 -->
  16 + <mescroll-body ref="mescrollRef" :up="upOption" @init="mescrollInit" :down="downOption" @down="downCallback"
  17 + @up="upCallback">
  18 + <view class="configuation-container">
  19 + <view class="configuation-item">
  20 + <view @click="openConfigDetail(item)" v-for="(item, index) in list" :key="index" class="item">
  21 + <image class="image" :src="item.icon || defaultConfigImage"></image>
  22 + <text class="name">{{ item.name }}</text>
  23 + </view>
  24 + </view>
  25 + </view>
  26 + <mescroll-empty v-if="!list.length" />
  27 + </mescroll-body>
  28 + <!-- 自带分页组件 -->
  29 + <view style="height: 60rpx;"></view>
  30 + </view>
  31 +</template>
  32 +
  33 +<script>
  34 + import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';
  35 + import api from '@/api/index.js'
  36 + import {
  37 + createScadaPageLink
  38 + } from './help';
  39 +
  40 + export default {
  41 + mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件)
  42 + data() {
  43 + return {
  44 + defaultConfigImage: '../../../static/test.png',
  45 + page: {
  46 + num: 0,
  47 + size: 10
  48 + },
  49 + downOption: {
  50 + auto: true //是否在初始化后,自动执行downCallback; 默认true
  51 + },
  52 + upOption: {
  53 + auto: false // 不自动加载
  54 + },
  55 + list: []
  56 + };
  57 + },
  58 + onLoad() {
  59 + // 隐藏原生的tabbar
  60 + uni.hideTabBar();
  61 + uni.setStorageSync('getConfiguration', {
  62 + isConfiguration: false
  63 + });
  64 + },
  65 + onUnload() {
  66 + uni.setStorageSync('getConfiguration', {
  67 + isConfiguration: false
  68 + });
  69 + uni.removeStorageSync('getConfiguration');
  70 + },
  71 + methods: {
  72 + inputChanged(e) {
  73 + this.page.num = 1;
  74 + this.loadData(1, e);
  75 + },
  76 + openConfigDetail(e) {
  77 + const href = createScadaPageLink(e)
  78 + uni.navigateTo({
  79 + url: 'configurationDetail?configurationHref=' + href
  80 + });
  81 + },
  82 + /*下拉刷新的回调 */
  83 + downCallback() {
  84 + //联网加载数据
  85 + this.page.num = 1;
  86 + this.loadData(1);
  87 + },
  88 + /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
  89 + upCallback() {
  90 + //联网加载数据
  91 + this.page.num += 1;
  92 + this.loadData(this.page.num);
  93 + },
  94 + async loadData(pageNo, organizationV) {
  95 + let httpData = {
  96 + page: pageNo,
  97 + pageSize: 10,
  98 + name: organizationV,
  99 + platform: 'phone'
  100 + };
  101 + const res = await api.homeApi.getConfigurationApi({
  102 + params: httpData,
  103 + custom: {
  104 + load: false
  105 + }
  106 + })
  107 + if (res) {
  108 + uni.stopPullDownRefresh();
  109 + this.mescroll.endByPage(res.items.length, res.total);
  110 + this.cameraTotal = res.total;
  111 + if (pageNo == 1) {
  112 + this.list = res.items;
  113 + } else {
  114 + this.list = this.list.concat(res.items);
  115 + }
  116 + }
  117 + }
  118 + }
  119 + };
  120 +</script>
  121 +
  122 +<style lang="scss" scoped>
  123 + @import '../static/configuration.scss';
  124 +</style>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 isConfiguration: true 20 isConfiguration: true
21 }); 21 });
22 if (e.configId !== null) { 22 if (e.configId !== null) {
23 - this.params = e.configId; 23 + this.params = e.configurationHref;
24 this.requestUrl(this.params); 24 this.requestUrl(this.params);
25 } 25 }
26 // 隐藏原生的tabbar 26 // 隐藏原生的tabbar
@@ -59,8 +59,8 @@ @@ -59,8 +59,8 @@
59 }); 59 });
60 const pathUrl = uni.getStorageSync('config'); 60 const pathUrl = uni.getStorageSync('config');
61 const userInfo = uni.getStorageSync('userInfo') 61 const userInfo = uni.getStorageSync('userInfo')
62 - this.showConfiguration =  
63 - `${pathUrl.baseURL}/?configurationId=${e}&userId=${userInfo.userId}&lightbox=1` 62 + console.log(this.params)
  63 + this.showConfiguration = this.params
64 } 64 }
65 } 65 }
66 }; 66 };
@@ -71,4 +71,4 @@ @@ -71,4 +71,4 @@
71 background: #f8f9fa; 71 background: #f8f9fa;
72 min-height: 100vh; 72 min-height: 100vh;
73 } 73 }
74 -</style> 74 +</style>
  1 +import config from '../../../config/baseUrl.js'
  2 +import {
  3 + atob,
  4 + btoa
  5 +} from './weapp.atob.js'
  6 +const getRandomString = () => Number(Math.random().toString().substring(2)).toString(36);
  7 +
  8 +export const ScadaModeEnum = {
  9 + PRIVATE_VIEW: 'PRIVATE_VIEW',
  10 + PUBLIC_VIEW: 'PUBLIC_VIEW',
  11 +}
  12 +
  13 +export const encode = (record) => {
  14 + let hash = JSON.stringify(record);
  15 + const mixinString = getRandomString()
  16 + .slice(0, 10)
  17 + .padEnd(10, getRandomString())
  18 + .split('')
  19 + .map((item) => (Math.random() > 0.5 ? item.toUpperCase() : item))
  20 + .join('');
  21 + hash = btoa(hash);
  22 + hash = hash.substring(0, 6) + mixinString + hash.substring(6);
  23 + hash = btoa(hash);
  24 + return hash;
  25 +};
  26 +
  27 +
  28 +export const createScadaPageLink = (
  29 + record,
  30 + mode = ScadaModeEnum.PRIVATE_VIEW,
  31 + open = false
  32 +) => {
  33 + const userInfo = uni.getStorageSync('userInfo')
  34 + const params = {
  35 + configurationId: record?.id,
  36 + organizationId: record?.organizationId,
  37 + mode: record?.viewType === ScadaModeEnum.PRIVATE_VIEW ? 'lightbox' : 'share',
  38 + platform: record?.platform,
  39 + userId: userInfo.userId
  40 + };
  41 +
  42 + if (record?.viewType === ScadaModeEnum.PUBLIC_VIEW) {
  43 + params.publicId = record.publicId;
  44 + }
  45 +
  46 + const hash = encode(params);
  47 +
  48 + const href = `${config.baseDrawioUrl}#${hash}`
  49 +
  50 + return href
  51 +};
  1 +var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  2 +var b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
  3 +export const btoa = function(string) {
  4 + string = String(string);
  5 + var bitmap, a, b, c, result = "",
  6 + i = 0,
  7 + rest = string.length % 3;
  8 + for (; i < string.length;) {
  9 + if ((a = string.charCodeAt(i++)) > 255 ||
  10 + (b = string.charCodeAt(i++)) > 255 ||
  11 + (c = string.charCodeAt(i++)) > 255)
  12 + throw new TypeError(
  13 + "Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range."
  14 + );
  15 + bitmap = (a << 16) | (b << 8) | c;
  16 + result += b64.charAt(bitmap >> 18 & 63) + b64.charAt(bitmap >> 12 & 63) +
  17 + b64.charAt(bitmap >> 6 & 63) + b64.charAt(bitmap & 63);
  18 + }
  19 + return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result;
  20 +};
  21 +
  22 +export const atob = function(string) {
  23 + string = String(string).replace(/[\t\n\f\r ]+/g, "");
  24 + if (!b64re.test(string))
  25 + throw new TypeError(
  26 + "Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
  27 + string += "==".slice(2 - (string.length & 3));
  28 + var bitmap, result = "",
  29 + r1, r2, i = 0;
  30 + for (; i < string.length;) {
  31 + bitmap = b64.indexOf(string.charAt(i++)) << 18 | b64.indexOf(string.charAt(i++)) << 12 |
  32 + (r1 = b64.indexOf(string.charAt(i++))) << 6 | (r2 = b64.indexOf(string.charAt(i++)));
  33 + result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) :
  34 + r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) :
  35 + String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255);
  36 + }
  37 + return result;
  38 +};
  39 +
  40 +function b64DecodeUnicode(str) {
  41 + return decodeURIComponent(exports.weAtob(str).replace(/(.)/g, function(p) {
  42 + var code = p.charCodeAt(0).toString(16).toUpperCase();
  43 + if (code.length < 2) {
  44 + code = "0" + code;
  45 + }
  46 + return "%" + code;
  47 + }));
  48 +}
  49 +
  50 +function base64_url_decode(str) {
  51 + var output = str.replace(/-/g, "+").replace(/_/g, "/");
  52 + switch (output.length % 4) {
  53 + case 0:
  54 + break;
  55 + case 2:
  56 + output += "==";
  57 + break;
  58 + case 3:
  59 + output += "=";
  60 + break;
  61 + default:
  62 + throw "Illegal base64url string!";
  63 + }
  64 + try {
  65 + return b64DecodeUnicode(output);
  66 + } catch (err) {
  67 + return exports.weAtob(output);
  68 + }
  69 +}
  70 +
  71 +function weappJwtDecode(token, options) {
  72 + if (typeof token !== "string") {
  73 + throw ("Invalid token specified");
  74 + }
  75 + options = options || {};
  76 + var pos = options.header === true ? 0 : 1;
  77 + try {
  78 + return JSON.parse(base64_url_decode(token.split(".")[pos]));
  79 + } catch (e) {
  80 + throw ("Invalid token specified: " + e.message);
  81 + }
  82 +}