quanyawei
2023-10-31 5fecc9e46d448df3de987504440c4fdd582f858e
fix:小程序秒级数据和登录授权
7 files deleted
27 files added
8 files modified
3417 ■■■■■ changed files
.env.dev.js 2 ●●● patch | view | raw | blame | history
manifest.json 148 ●●●● patch | view | raw | blame | history
pages.json 7 ●●●●● patch | view | raw | blame | history
pages/actionChange/agencyPage/index.vue 2 ●●● patch | view | raw | blame | history
pages/actionChange/components/rectificationInfor.vue 7 ●●●● patch | view | raw | blame | history
pages/actionChange/myInfor/index.vue 2 ●●●●● patch | view | raw | blame | history
pages/actionChange/newPage/index.vue 4 ●●●● patch | view | raw | blame | history
pages/actionChange/secondLevelData/index.vue 596 ●●●●● patch | view | raw | blame | history
pages/actionChange/secondLevelData/parameter.json 44 ●●●●● patch | view | raw | blame | history
pages/login/login.vue 18 ●●●●● patch | view | raw | blame | history
static/img/headSculpture.png patch | view | raw | blame | history
static/img/shouye.png patch | view | raw | blame | history
static/img/shouyeClick.png patch | view | raw | blame | history
static/img/wode-.png patch | view | raw | blame | history
static/img/wodeClick.png patch | view | raw | blame | history
static/img/xinjian.png patch | view | raw | blame | history
static/img/xinjianClick.png patch | view | raw | blame | history
uni_modules/uni-popup/changelog.md 68 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/components/uni-popup-dialog/keypress.js 45 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue 275 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue 143 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue 187 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/components/uni-popup/i18n/en.json 7 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/components/uni-popup/i18n/index.js 8 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json 7 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json 7 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/components/uni-popup/keypress.js 45 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/components/uni-popup/popup.js 26 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/components/uni-popup/uni-popup.vue 473 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/package.json 87 ●●●●● patch | view | raw | blame | history
uni_modules/uni-popup/readme.md 17 ●●●●● patch | view | raw | blame | history
uni_modules/uni-transition/changelog.md 22 ●●●●● patch | view | raw | blame | history
uni_modules/uni-transition/components/uni-transition/createAnimation.js 131 ●●●●● patch | view | raw | blame | history
uni_modules/uni-transition/components/uni-transition/uni-transition.vue 286 ●●●●● patch | view | raw | blame | history
uni_modules/uni-transition/package.json 84 ●●●●● patch | view | raw | blame | history
uni_modules/uni-transition/readme.md 11 ●●●●● patch | view | raw | blame | history
uni_modules/ws-wx-privacy/changelog.md 22 ●●●●● patch | view | raw | blame | history
uni_modules/ws-wx-privacy/components/ws-wx-privacy/util.js 51 ●●●●● patch | view | raw | blame | history
uni_modules/ws-wx-privacy/components/ws-wx-privacy/ws-wx-privacy.vue 287 ●●●●● patch | view | raw | blame | history
uni_modules/ws-wx-privacy/package.json 85 ●●●●● patch | view | raw | blame | history
uni_modules/ws-wx-privacy/readme.md 122 ●●●●● patch | view | raw | blame | history
utils/websoket.js 91 ●●●●● patch | view | raw | blame | history
.env.dev.js
@@ -1,6 +1,6 @@
const config = {
    // baseUrl: "http://120.26.43.34:8081/api/", //测试
    baseUrl: "https://qx.7drlb.com/api", //生产
    // baseUrl: "http://192.168.0.9:8081/api", //生产
    // baseUrl: "http://192.168.0.12:8081/api", //生产
};
module.exports = config;
manifest.json
@@ -1,75 +1,75 @@
{
    "name" : "test",
    "appid" : "__UNI__93C3197",
    "description" : "",
    "versionName" : "1.0.0",
    "versionCode" : "100",
    "transformPx" : false,
    /* 5+App特有相关 */
    "app-plus" : {
        "usingComponents" : true,
        "nvueStyleCompiler" : "uni-app",
        "compilerVersion" : 3,
        "splashscreen" : {
            "alwaysShowBeforeRender" : true,
            "waiting" : true,
            "autoclose" : true,
            "delay" : 0
        },
        /* 模块配置 */
        "modules" : {},
        /* 应用发布信息 */
        "distribute" : {
            /* android打包配置 */
            "android" : {
                "permissions" : [
                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                    "<uses-feature android:name=\"android.hardware.camera\"/>",
                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
                ]
            },
            /* ios打包配置 */
            "ios" : {},
            /* SDK配置 */
            "sdkConfigs" : {}
        }
    },
    /* 快应用特有相关 */
    "quickapp" : {},
    /* 小程序特有相关 */
    "mp-weixin" : {
        "appid" : "wx41f4c3c007545088",
        "setting" : {
            "urlCheck" : false,
            "es6" : true,
            "postcss" : true,
            "minified" : true
        },
        "usingComponents" : true
    },
    "mp-alipay" : {
        "usingComponents" : true
    },
    "mp-baidu" : {
        "usingComponents" : true
    },
    "mp-toutiao" : {
        "usingComponents" : true
    },
    "uniStatistics" : {
        "enable" : false
    },
    "vueVersion" : "2"
}
    "name": "test",
    "appid": "__UNI__93C3197",
    "description": "",
    "versionName": "1.0.0",
    "versionCode": "100",
    "transformPx": false,
    /* 5+App特有相关 */
    "app-plus": {
        "usingComponents": true,
        "nvueStyleCompiler": "uni-app",
        "compilerVersion": 3,
        "splashscreen": {
            "alwaysShowBeforeRender": true,
            "waiting": true,
            "autoclose": true,
            "delay": 0
        },
        /* 模块配置 */
        "modules": {},
        /* 应用发布信息 */
        "distribute": {
            /* android打包配置 */
            "android": {
                "permissions": ["<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                    "<uses-feature android:name=\"android.hardware.camera\"/>",
                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
                ]
            },
            /* ios打包配置 */
            "ios": {},
            /* SDK配置 */
            "sdkConfigs": {}
        }
    },
    /* 快应用特有相关 */
    "quickapp": {},
    /* 小程序特有相关 */
    "mp-weixin": {
        "appid": "wxf95fb77e0b1f8c09",
        "__usePrivacyCheck__": true,
        "setting": {
            "urlCheck": false,
            "es6": true,
            "postcss": true,
            "minified": true
        },
        "usingComponents": true
    },
    "mp-alipay": {
        "usingComponents": true
    },
    "mp-baidu": {
        "usingComponents": true
    },
    "mp-toutiao": {
        "usingComponents": true
    },
    "uniStatistics": {
        "enable": false
    },
    "vueVersion": "2"
}
pages.json
@@ -44,6 +44,13 @@
                "disableSwipeBack": true,
                "navigationStyle": "custom"
            }
        }, {
            "path": "pages/actionChange/secondLevelData/index",
            "style": {
                "navigationBarTitleText": "秒级数据",
                "enablePullDownRefresh": false,
                "disableSwipeBack": true
            }
        }
    ]
    // "tabBar": {
pages/actionChange/agencyPage/index.vue
@@ -349,7 +349,7 @@
                    id: e.allocationId
                }).then(res => {
                    let data = res.data
                    data.pageState = data.state === 50 || data.state === 40 ? 'view' : pageState
                    data.pageState = e.stateName === '待处理' ? pageState : 'view'
                    let myData = JSON.stringify(data)
                    uni.navigateTo({
                        url: '/pages/actionChange/workOrderDetails/index?infor=' + myData,
pages/actionChange/components/rectificationInfor.vue
@@ -145,8 +145,11 @@
                    let name = item.fileType === 1 ? 'name.png' : 'name.mp4'
                    this.fileList.push(`${this.baseUrl}/file/preview/${item.fileId}?${name}`) // 原图
                })
                console.log('this.fileList', this.basicInfor.fileBaseList)
                console.log('this.fileList', this.fileList)
            }
            let userInfor = JSON.parse(uni.getStorageSync('userInfor') || '{}')
            console.log('userInfor', userInfor)
            if (this.basicInfor.pageState === 'edit') {
                this.form.changeName = userInfor.userName
            }
        },
        methods: {
pages/actionChange/myInfor/index.vue
@@ -11,6 +11,8 @@
                <u-cell icon="account-fill" title="账号" :value="userInfor.account"></u-cell>
                <u-cell icon="integral-fill" title="责任单位" :value="unitName"></u-cell>
                <u-cell icon="phone-fill" title="手机号" :value="userInfor.mobile"></u-cell>
                <u-cell icon="clock-fill" title="查看秒级数据" v-if="userInfor.device===1" isLink
                    url="/pages/actionChange/secondLevelData/index"></u-cell>
            </u-cell-group>
        </view>
        <view class="bunts">
pages/actionChange/newPage/index.vue
@@ -265,8 +265,8 @@
                    this.form.escalationUnitId = data
                    this.sumbitForm.escalationUnitId = userInfor.unitId
                }
                this.form.escalationName = userInfor.name || ''
                this.sumbitForm.escalationName = userInfor.name || ''
                this.form.escalationName = userInfor.userName || ''
                this.sumbitForm.escalationName = userInfor.userName || ''
                this.form.investigationType = 1
                this.sumbitForm.investigationType = 1
                console.log('this.sumbitForm', this.sumbitForm)
pages/actionChange/secondLevelData/index.vue
New file
@@ -0,0 +1,596 @@
<template>
    <view class="rootBg">
        <view class="">
            <view class="ridoa">
                <u-radio-group v-model="value" placement="row" :size='radioOption.size'
                    :labelColor='radioOption.labelColor' :labelSize='radioOption.labelSize' @change='changeSearchType'>
                    <u-radio activeColor="#19be6b" label="通过站点查询" name="0" :labelSize='radioOption.labelSize'
                        :labelColor='radioOption.labelColor'></u-radio>
                    <u-radio activeColor="#19be6b" label="通过设查号询" name="1" :labelSize='radioOption.labelSize'
                        :labelColor='radioOption.labelColor'></u-radio>
                </u-radio-group>
            </view>
            <view class="" v-if="value==='1'">
                <u-input placeholder="请输入Mac号" :placeholderStyle='placeholderStyle' color="#fff" v-model='macName'>
                    <template slot="suffix">
                        <u-button @tap="searchMacList" text="查询" type="success" size="small"></u-button>
                    </template>
                </u-input>
            </view>
            <view class="" v-else>
                <u-form ref="uForm" label-width="80" :model="form">
                    <u-form-item border-bottom @click="showeEscalationTime = true ;hideKeyboard('orgName','orgId')">
                        <u-input v-model="form.orgName" disabled disabled-color="#ffffff" placeholder="请选择组织"
                            type="select" />
                    </u-form-item>
                    <u-form-item border-bottom @click="selectSite">
                        <u-input v-model="form.siteName" disabled disabled-color="#ffffff" placeholder="请选择站点"
                            type="select" />
                    </u-form-item>
                </u-form>
                <u-picker :show="showeEscalationTime" :columns="columns" @confirm="selectBack" keyName="name"
                    @cancel="showeEscalationTime = false"></u-picker>
            </view>
        </view>
        <view v-if="wsData2">
            <u-cell title="风向:" :value="windDirData"></u-cell>
        </view>
        <view class="boxPadd">
            <u-list v-if="showData.length>0">
                <u-list-item v-for="(item, index) in showData" :key="index">
                    <u-row customStyle="margin-bottom: 10px">
                        <u-col span="3">
                            <view>{{ item.sensorCode | sensorFilter}}</view>
                        </u-col>
                        <u-col span="6" textAlign="right">
                            <u-line-progress :percentage="item.alarm" :activeColor="item.colour"></u-line-progress>
                        </u-col>
                        <u-col span="3" textAlign="right">
                            <view>{{ item.value || ''}} </view>
                        </u-col>
                    </u-row>
                </u-list-item>
            </u-list>
        </view>
        <u-toast ref="uToast"></u-toast>
        <u-modal :show="showModel" title='请选择Mac号' showCancelButton @cancel='showModel=false' @confirm='selectMac'>
            <view class="slot-content">
                <u-radio-group v-model="modeleMacSelect" iconPlacement="right" placement='column' borderBottom='true'>
                    <view v-for="(item,index) in macList" :key="index" class="ridioBox">
                        <u-radio activeColor="#19be6b" :label="item.mac" :name="item.mac"></u-radio>
                    </view>
                </u-radio-group>
            </view>
        </u-modal>
    </view>
</template>
<script>
    import json from '@/pages/actionChange/secondLevelData/parameter.json'
    import wsRequest from '@/utils/websoket.js'
    export default {
        data() {
            return {
                modeleMacSelect: '',
                value: '0',
                showModel: false,
                showeEscalationTime: false,
                columns: [],
                form: {
                    orgName: '',
                    orgId: '',
                    siteName: '',
                    siteId: ''
                },
                selectForm: {
                    name: '',
                    id: ''
                },
                macList: [],
                radioOption: {
                    size: '20px',
                    labelColor: '#fff',
                    labelSize: '18px'
                },
                placeholderStyle: 'color: #fff',
                macName: '',
                defaultMonitorItems: [],
                chartSensorKey: [],
                coreMonitorItems: [],
                fixedMonitorItems: [],
                totalArray: [],
                alarmLevel: null,
                aqi: 0,
                baseUrl: '',
                windDir: 'null',
                windDeg: 180,
                wsData2: null,
                // 报警进度条
                alarmProgress: {},
                // 报警颜色
                alarmColour: {},
                // 报警圆环图片
                alarmBg: {},
                timer: '',
                isLoading: true
            }
        },
        filters: {
            // 过滤器替换websocket实时数据的key值
            sensorFilter: function(value) {
                if (!value) return ''
                return json[value]
            }
        },
        computed: {
            windDirData() {
                if (this.wsData2) {
                    console.log('this.windDir', this.windDir)
                    return `${this.windDir} (${this.wsData2.a01008})`
                } else {
                    return ''
                }
            },
            showData() {
                return [...this.defaultMonitorItems, ...this.coreMonitorItems]
            }
        },
        created() {
            this.getOrgs()
        },
        onUnload() {
            let that = this
            this.socketTask.close()
            that.isLoading = false
            that.timer = ''
        },
        methods: {
            getData() {
                this.queryAlarmByMac()
                this.getHourlyAqi()
                this.sensorLayout()
            },
            changeSearchType() {
                this.macName = ''
            },
            selectMac() {
                this.macName = this.modeleMacSelect
                this.showModel = false
                if (this.socketTask) {
                    this.socketTask.onClose()
                }
                this.getData()
            },
            searchMacList() {
                this.$http.httpGet('/AppDevice/fuzzySearch', {
                    mac: this.macName
                }).then(res => {
                    this.showModel = true
                    if (res.data && res.data.length > 10) {
                        this.macList = res.data.slice(0, 10)
                    }
                }).catch(res => {
                    uni.$u.toast(res)
                })
            },
            selectSite() {
                if (this.form.orgId === '') {
                    uni.showToast({
                        title: '请先选择组织!',
                        icon: 'none',
                    })
                } else {
                    this.selectForm = {
                            name: 'siteName',
                            id: 'siteId'
                        },
                        this.getSites()
                }
            },
            hideKeyboard(name, id) {
                this.selectForm = {
                    'name': name,
                    'id': id
                }
                this.getOrgs()
            },
            selectBack(e) {
                if (this.selectForm.name === 'orgName') {
                    this.form = {
                        orgName: '',
                        orgId: '',
                        siteName: '',
                        siteId: ''
                    }
                } else {
                    this.macName = e.value[0].mac
                    if (this.socketTask) {
                        this.socketTask.onClose()
                    }
                    this.getData()
                }
                this.form[this.selectForm.name] = e.value[0].name
                this.form[this.selectForm.id] = e.value[0].id
                this.showeEscalationTime = false
            },
            getOrgs() {
                this.$http.httpGet('/AppDevice/selectOrganization').then(res => {
                    this.columns = []
                    this.columns.push(res.data)
                }).catch(res => {
                    uni.$u.toast(res)
                })
            },
            getSites() {
                let params = {
                    organizationId: this.form.orgId
                }
                this.$http.httpGet('/AppDevice/selectDevice', params).then(res => {
                    console.log(res)
                    this.columns = []
                    this.columns.push(res.data)
                    this.showeEscalationTime = true
                }).catch(res => {
                    uni.$u.toast(res)
                    console.log(res)
                })
            },
            sensorLayout() {
                let params = {
                    mac: this.macName
                }
                this.$http.httpGet('/organizationLayout/getLayoutByMac', params).then(res => {
                    this.chartSensorKey = res.data.chartSensorKey
                    this.coreMonitorItems = res.data.coreMonitorItems
                    this.defaultMonitorItems = res.data.defaultMonitorItems
                    this.fixedMonitorItems = res.data.fixedMonitorItems
                    this.totalArray.push(...this.coreMonitorItems, ...this.defaultMonitorItems, ...this
                        .fixedMonitorItems)
                    this.getSensorMonthAvg()
                    this.connectSocket()
                }).catch(res => {
                    uni.$u.toast(res)
                    console.log(res)
                })
            },
            // 请求单台设备某参数月平均值
            getSensorMonthAvg() {
                let params = {
                    sensorCode: this.chartSensorKey[0].sensorCode,
                    mac: this.macName
                }
                this.$http.httpGet('/deviceInfo/getMonthAvg', params).then(res => {
                    this.average = res.data.avg
                }).catch(res => {
                    uni.$u.toast(res)
                    console.log(res)
                })
            },
            // 设备因子报警值
            queryAlarmByMac() {
                let params = {
                    mac: this.macName
                }
                this.$http.httpGet('/deviceInfo/queryAlarmByMac', params).then(res => {
                    this.alarmLevel = res.data.alarmLevel
                }).catch(res => {
                    uni.$u.toast(res)
                    console.log(res)
                })
            },
            // 请求单台设备一个小时
            getHourlyAqi() {
                let params = {
                    mac: this.macName
                }
                this.$http.httpGet('/deviceInfo/getHourlyAqi', params).then(res => {
                    this.aqi = res.data.AQI
                }).catch(res => {
                    uni.$u.toast(res)
                    console.log(res)
                })
            },
            handlerMsg(msg) {
                this.wsData2 = JSON.parse(msg.data)
                if (this.wsData2.dustld) {
                    this.wsData2.dustld = this.wsData2.dustld.replace(/g/, 'ug')
                }
                // 风向算法
                if (this.wsData2.a01008) {
                    var windDirs = Number(this.wsData2.a01008.substr(0, this.wsData2.a01008.length - 1))
                    this.windDeg = windDirs
                    if (windDirs === 0) {
                        this.windDir = '北风'
                    } else if (windDirs > 0 && windDirs < 90) {
                        this.windDir = '东北风'
                    } else if (windDirs === 90) {
                        this.windDir = '东风'
                    } else if (windDirs > 90 && windDirs < 180) {
                        this.windDir = '东南风'
                    } else if (windDirs === 180) {
                        this.windDir = '南风'
                    } else if (windDirs > 180 && windDirs < 270) {
                        this.windDir = '西南风'
                    } else if (windDirs === 270) {
                        this.windDir = '西风'
                    } else if (windDirs > 270 && windDirs < 360) {
                        this.windDir = '西北风'
                    }
                }
                this.alarmColour = {}
                this.alarmProgress = {}
                this.alarmBg = {}
                // 报警等级
                for (const key in this.wsData2) {
                    if (this.chartSensorKey && key === this.chartSensorKey[0].sensorCode) {
                        this.chartSensorKey[0].value = this.wsData2[key]
                    }
                    for (const keys in this.alarmLevel) {
                        // 遍历进度条颜色
                        if (key === keys && JSON.parse(this.alarmLevel[keys])) {
                            if (parseFloat(this.wsData2[key]) >= parseFloat(JSON.parse(this.alarmLevel[keys])[5])) {
                                this.alarmColour[keys] = '#000000'
                                this.alarmBg[keys] = 5
                            } else if (parseFloat(this.wsData2[key]) >= parseFloat(JSON.parse(this.alarmLevel[keys])[4])) {
                                this.alarmColour[keys] = '#c00261'
                                this.alarmBg[keys] = 4
                            } else if (parseFloat(this.wsData2[key]) >= parseFloat(JSON.parse(this.alarmLevel[keys])[3])) {
                                this.alarmColour[keys] = '#fc0101'
                                this.alarmBg[keys] = 3
                            } else if (parseFloat(this.wsData2[key]) >= parseFloat(JSON.parse(this.alarmLevel[keys])[2])) {
                                this.alarmColour[keys] = '#ff8202'
                                this.alarmBg[keys] = 2
                            } else if (parseFloat(this.wsData2[key]) >= parseFloat(JSON.parse(this.alarmLevel[keys])[1])) {
                                this.alarmColour[keys] = '#fdff00'
                                this.alarmBg[keys] = 1
                            } else {
                                this.alarmColour[keys] = '#00ff01'
                                this.alarmBg[keys] = 0
                            }
                        } else if (key === keys) {
                            this.alarmColour[keys] = '#00ff01'
                            this.alarmBg[keys] = 0
                        }
                        // 遍历进度条百分比
                        if (key === keys && JSON.parse(this.alarmLevel[keys])) {
                            if (JSON.parse(this.alarmLevel[keys])[5]) {
                                const percentage = Math.round(
                                    (parseFloat(this.wsData2[key]) / parseFloat(JSON.parse(this.alarmLevel[keys])[
                                    5])) * 100)
                                this.alarmProgress[keys] = percentage
                            } else if (JSON.parse(this.alarmLevel[keys])[4]) {
                                const percentage = Math.round(
                                    (parseFloat(this.wsData2[key]) / parseFloat(JSON.parse(this.alarmLevel[keys])[
                                    4])) * 100)
                                this.alarmProgress[keys] = percentage
                            } else if (JSON.parse(this.alarmLevel[keys])[3]) {
                                const percentage = Math.round(
                                    (parseFloat(this.wsData2[key]) / parseFloat(JSON.parse(this.alarmLevel[keys])[
                                    3])) * 100)
                                this.alarmProgress[keys] = percentage
                            } else if (JSON.parse(this.alarmLevel[keys])[2]) {
                                const percentage = Math.round(
                                    (parseFloat(this.wsData2[key]) / parseFloat(JSON.parse(this.alarmLevel[keys])[
                                    2])) * 100)
                                this.alarmProgress[keys] = percentage
                            } else if (JSON.parse(this.alarmLevel[keys])[1]) {
                                const percentage = Math.round(
                                    (parseFloat(this.wsData2[key]) / parseFloat(JSON.parse(this.alarmLevel[keys])[
                                    1])) * 100)
                                this.alarmProgress[keys] = percentage
                            } else if (JSON.parse(this.alarmLevel[keys])[0]) {
                                const percentage = Math.round(
                                    (parseFloat(this.wsData2[key]) / parseFloat(JSON.parse(this.alarmLevel[keys])[
                                    0])) * 100)
                                this.alarmProgress[keys] = percentage
                            }
                        } else if (key === keys) {
                            this.alarmProgress[keys] = 0
                        }
                        if (this.alarmProgress[keys] > 100) {
                            this.alarmProgress[keys] = 100
                        }
                    }
                }
                // 实时数据改变合并数组的值
                for (let i = 0; i < this.totalArray.length; i++) {
                    for (const key in this.wsData2) {
                        if (key !== 'time') {
                            // 获取数据的小数
                            var tempDecimal = this.wsData2[key].replace(/[^\d.]/g, '').split('.')[1]
                            if (this.totalArray[i].sensorCode === key) {
                                // 臭气和湿度保留整数
                                if (this.totalArray[i].sensorCode === 'a19002') {
                                    this.totalArray[i].value = parseInt(this.wsData2[key])
                                } else if (this.totalArray[i].sensorCode === 'a01002') {
                                    this.totalArray[i].value = parseInt(this.wsData2[key]) + '%'
                                    // 除了TVOCQ其他因子数据小数是零的就去掉小数
                                } else if (this.totalArray[i].sensorCode !== 'a99054' && Number(tempDecimal) === 0) {
                                    this.totalArray[i].value = parseInt(this.wsData2[key]) + this.wsData2[key].split(' ')[
                                        1]
                                } else {
                                    this.totalArray[i].value = this.wsData2[key]
                                }
                            }
                        }
                    }
                    for (const key in this.alarmProgress) {
                        if (this.totalArray[i].sensorCode === key) {
                            this.totalArray[i].alarm = this.alarmProgress[key]
                        }
                    }
                    console.log('this.totalArray', this.totalArray)
                    console.log('this.alarmColour', this.alarmColour)
                    for (const key in this.alarmColour) {
                        if (this.totalArray[i].sensorCode === key) {
                            this.totalArray[i].colour = this.alarmColour[key]
                        }
                    }
                    for (const key in this.alarmBg) {
                        if (this.totalArray[i].sensorCode === key) {
                            this.totalArray[i].bg = this.alarmBg[key]
                        }
                    }
                }
            },
            //连接websocket
            connectSocket() {
                if (!this.isLoading) {
                    this.socketTask.close()
                    this.socketTask = null
                }
                this.baseUrl = this.$storage.get('baseUrl')
                let that = this
                let socketUrl = this.baseUrl + '/singleDevice/' + this.macName
                socketUrl = socketUrl.replace('https', 'wss').replace('http', 'ws')
                console.log('调用连接websocket')
                this.socketTask = uni.connectSocket({
                    url: socketUrl,
                    success(res) {
                        console.log('websocket连接成功')
                        that.isLoading = true
                    },
                    fail(err) {
                        console.log('报错', err)
                    }
                }, )
                this.socketTask.onOpen(function(res) {
                    console.log('WebSocket连接已打开!')
                    that.isLoading = true
                    // that.getStatus()
                    // that.heart()
                })
                this.socketTask.onMessage(function(res) {
                    console.log('收到服务器内容:' + res.data)
                    that.handlerMsg(res) //这里是对获取到的数据进行操作
                })
                this.socketTask.onError(function(res) {
                    console.log('WebSocket连接打开失败,请检查!')
                    console.log(res)
                    // this.isSuccess = false
                    // that.connectSocket()
                    //进入重新连接
                    that.reconnect()
                })
                // // 监听连接关闭 -
                this.socketTask.onClose(e => {
                    console.log('WebSocket连接关闭!')
                    clearInterval(that.timer)
                    that.timer = ''
                    if (!that.isClose) {
                        that.reconnect()
                    }
                })
                console.log(this.socketTask)
            },
            //进入重新连接
            reconnect() {
                console.log('进入断线重连')
                this.socketTask.close()
                this.socketTask = null
                if (this.isLoading) {
                    this.connectSocket()
                }
            },
            //发送消息
            sendSocketMessage(msg) {
                console.log('发送信息')
                console.log(msg)
                return new Promise((reslove, reject) => {
                    this.socketTask.send({
                        data: msg,
                        success(res) {
                            console.log('发送成功')
                            reslove(res)
                        },
                        fail(res) {
                            console.log('发送失败')
                            console.log(res)
                            reject(res)
                        }
                    })
                })
            },
            //心跳
            heart() {
                let that = this
                clearInterval(this.timer)
                this.timer = ''
                let msg = {
                    'type': 'heartbeat',
                }
                this.timer = setInterval(() => {
                    that.sendSocketMessage(JSON.stringify(msg)).then(res => {
                        console.log('心跳成功')
                    }).catch(res => {
                        console.log('发送失败')
                        console.log((res))
                    })
                }, 2000)
            },
            beforeDestroy() {
                if (this.socketTask) {
                    this.socketTask.close()
                    this.socketTask = null
                }
                if (this.timer) {
                    clearInterval(this.timer) // 在Vue实例销毁前,清除我们的定时器
                }
            },
        }
    }
</script>
<style scoped lang="scss">
    .rootBg {
        min-height: 100%;
        color: #fff;
        /* 背景图垂直、水平均居中 */
        background-position: center center;
        /* 背景图不平铺 */
        background-repeat: no-repeat;
        /* 当内容高度大于图片高度时,背景图像的位置相对于viewport固定 */
        background-attachment: fixed;
        /* 让背景图基于容器大小伸缩 */
        background-size: cover;
        background-image: url('data:image/jpeg;base64,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se1AznigBXAGMU7aMUw570vzYoAFAOaRgAeKBntSEHPNAEm0YpqAGk+bHtQM54oAGAB4pwUYpNuQSTyKQbscUAKo5NTWygXtv/10X+dVxnPHWp7XP263z/z0X+dDGh13/wAftx/10b+dQ96sXo/02f8A66N/OoMUlsUFFAGT1opiEpaAKX60hiYopTz2ooASilxRQIbS0uKMUANopcUYoASloo60wAUUuKVcA8jPtSEJxTgBtznn0ptLQAtLSAU4UAKjsn3TSMSxyeTRRQAlFLS0ANoxTsUYoENxRS0YoATFLRRTATFKAMHP4UUUhAqFs47cmk7UtJQAYGaDjPtSUUwCkpaSgAooxRQAUoxjmkpaAFU4NK5BGKaBk4pzKAMigAUgDFJkb80qqCM0m35sUAOZhtoVgBikZQBkUqoMZoEJuG7PalYgrxQmElBIDAdjQ4HJ6UgFVhtpA2HyKFUY5oC/NigBXbceTye9OyBxnpTXTC7gOKAoxQIQEbiaVyMYo2jdgE496GUAcUDHKUxycACmBhuz604KMUwjBoAc5GKbR6ZoOM8dKACigiigAooFL+HFMQlLn5SMD60maKAEooooAKKVVLZI7cmkoEFFFFAC0lFFACqpY4H60UlOU7WzgH2oAbQaO9FADi25QMAbfTvTaMUUAGaWhlCtjIPuKTvQAtGaSlBI6UAFFJRQAtHJ6mikoELSUUoFACUUUUAFFFFABR2oooAKWijk9KACiiigBy43c0r4xTKKAJFI200Eb6UKMUm35sUgFfGKUEYprKAM0BRimAKcOaHIx70gX5iKVxgZoAchHGenem5XzG28L2oCjFH3m57elAwcjHvSgjFNZcDNNoAD1ooooASilpKACiikoAWiiigAooooAKKKKAEpe1JR2oAKKKKAClIwaONvQ59aCSxyetACUUUUDCneU2wPjIPpTaAzDoSKAEooooAVSo+8M0lFFAB3opKWgBKO9FFABRRSUDCiiigAooooAKKKKACiiigYlFFLxigBKKKKACiiigABIzjvSUtJQAUY4zRRQMKMcZ7UGkoAWkpcUlAEgYYpoYbiacFG3kU0AbiKAFZgRxShhikZQBxShRigBqsNxJ70OQeBQoG4+1DgDpQA4MMU1SAc07aMU1QCaABiCKdvGOtNYACnbRigBqnmhiCKRRk0rgADFAC7hikVgCc0oUYpFAJNAAzZ4FO3jFNcAdKdtGKAGqcE0MQelCjk0MAKAHbhimqQDzTtoxTUUFuaAByD0pQwxSOoB4pwUYoAap+b61Pbn/Trceki/wA6gUZY1NbAC9t/+ui/zoYLcnvAPts//XRv51XIFT3hP22f/ro386gPPWpRTG8UUtFMAoooxQAUD6UUUAAFGKeo9qNtIBmKKftNNIoAQ9aMUuKSgBKMUtFMAopc8Y7UlABQKUUuPSgApaSlFAC4oopcUAGKUDPelA55o6dOlIQ3FGKdijFADcUYNLiigQ3FFPABU5OMfrQ3Kg/hQAylHDcj8KMc0hyTk0wFZt3YCm4paKBCdaSnc0mKBjaDjPBzSmkpiEopaKAEoopcEdRQAZxzRknqaKKQCru7dKTnPvT1YYpAfnzQAjE45pydOTgUMwxilVhtxQBHzn3px3d6AfmzTmIK4pgNG7HFIM596kUjFKEb723g0hEbFsYPSlG7HFLJgcA5oDDFADRnPHWlYnvQCNxNKxUjHegABbFNp4YYpowzYJwKAEopT1POaSgApc/KB6UlLQADGDkUBiFIHQ0EcnByKSgQUlLRimAlFLikoAKUnJ4GKMUYxQAlFLSYoEFKTk80lFABS0lLQAlL+FFKWLAA9hgUAIaQilooASiiigAooooEFGCegopQxXOD1oASilxSUDCiiigAoopQrNnAzjrQAlGaKKADvSmkooAU44xmlVipyKSigQVatoVZN7DJ7VVqWGdohjGVNS720AmuIUCb1GCOtVQQDyMipJbgyjbjC1Fx3oV7agxwLY4pMnPvTwRimhhuqgEYnvQC2KVyMUoYYoGMBOeOtDE96UEBjSuRigBxCiMFGJPcGosnOaerDFMJyTQApYmkpKWgApKX+VJQAUUUUAFFFBGDQAUmaKKAFoU4YHAPsaKSgBSckn1pKWkoAMUrNuI4AwO1FJQAUUUUAGTjGeKKBjPIzRQAUlLSUDCiiigAooooAKKKBjPNABj1NFSvCFTcDzUVFwEPtQODRRQAdcmigDIJ7CigYlFFFABRRRQAUcUUUDCkpaM8YoAKSlpKAClJyaCMdaSgApcfLnIpKKACgHGfekpcZXOaAEpdp27u1JRk4x2oAUYOcmkpKKBi0lFFAD8MBgU0Zzx1p4cYpobBz60AI2e9KA2OOlDMDwKUMMUANGc8daGz3pQcMc96GYHpQAANj2poznjrT92BzSAqOec+lACNu70uG2+1DMD0pd4xQAwZzx1pTkdaFODSswPSgACsVJHSmjOeKeHGKarYPPegBGznmlw2KGbPSnbxigYxc54pWznmhWweaGbPSgBfmxSDJOR1p28Y96RWA60CBgQeaAGxxQxz0pQ4xQA0Zzx1qe1z9ut8/wDPRf51CrYOT3qe2YG9t8f89F/nQwRLeD/TZ/8Aro386gqzd/8AH7OP+mjfzqEipRbQyinhaNlArDMUVJs4pNlFwsMxTgmaeqgU8ACi40hFTjmnhM9KTNLmpKGlaiZcc1OaYy5poTIaTt0p5GOKbTJExRS0UAJRS0UAL1PFFFFABS4o60YoAdkYxiikp4AxmgAAo/ClxSdaQAKKXFHtTEJjPSkIp1GKAG4pKfj36dqbigQ3qaKdikx+VACUUtFADSOBRTjzSc4x2pgNxQad/KkxQA0ijHGaXFGKABlAUEHJPUUhJPU9KMUHmgBKKXFJigB6qMUgX5sUo3Y4pozn3oAcygDIpQgxTW3Y5pRuxxQIQL82KcygDimhj075pWzjmgByqMZqXzcrtx2xUI3beOlIM5460gsKygDIpQoxTW3YGelKC2OKYAq/NihlAGRTckHPelJJ60AGBt6/NSU5QC3zHA9aSgBKWiigAoNFHSgAoClhkDgUGjJAwDQISiilZixyaAEoo4x0ooAUDJxSspU4NGAYye4pO1AgooooASjFLSs2VUccUAN7miigHBpiCilPU4ptABS0lKDhSPWgAooxR2FAAMZ+bpRn06UUlABRRRQAUUU4IdoYnC5xmgBtFKRgkA596SgAoyRkA9etFFAABk4FFFHFABRRRQAUoBPA60lAJHSgQ5gAcA5pKOtJQAtKrYBGBzTaKAJAoxQ21mGBtAHQU0MQMUmcHOaBisoA4pQoxTSxNAY8CgAC5Yj0pWUAZFIco3vQWJ+lADaKKKAF4zSUUUAFFKaSgAooooAKKKKACiiigAooooAKSiigAooooAKKKUjBxnNAxKKKM0AFJSkjPAwKSgAooooAKKKSgBaKKSgBSxIwSTSUUUDCiiigBKM0UUALSUUUAFLgmkozjvQAUlLRQMSiiigAooooAKKKKAEopaSgAooooGFFFFABRRRQAGkoooAkCjFNC/MRSAkDFAJBzQA51AGRShRimEk9aUMQKAEPWkoooAM8YooooGFFFFABRRRQBJtGKjNLuOMUlAhKk2DFR075se1AAqgmhlA6UgznilJ5+YZoGO2DFNVc5zR82PakBPagQ5hjpShBimNnvSjdj2oAVVyxFTWoxe25H/PRf51X3EGprQk31vn/AJ6L/OhjRcvB/ps//XRv51Ae1WLs/wCmz/8AXRv51XPNQi2ISSaMmjFGKYh4aimjJPFPApALRS4oxQMTrThQBS/SkAUhp1NIoAjNNYYp5U0mzPFMQwKTQRzgVPtwuKjIFFwGYoAp4UUuMUAM20bfenE+tJTAQUuKU4zx0oHSkIAKUUUooABR+FLRQAUUoGacV/SgBmKCMngYxTiKMUCG4pMU4gjrSEUAJikNOxxRigBtJinYowe9MQ3HWk7U/FAwOvSgBvXrRgU7A/D0pMUANNNxUnGDkUmKAGDINJipMUmKAGYoxTsUYoAVSMUgI3Zp4UYpoUbsdqAByCMChWGKVkAHFAQY5pgNDcn0pWIIxQEy+KVlAHFAhFYYpARuzTggxzSBfmxQAMQRgU4ONmKRlAGRQEGKQDDySaMUrLtOM5oyaYCUHGBjr3opaAEopaTFACkg4wPrQDjORmko60AFFLSUABOaSnCkoEJRSgkHI60HJOT1oASloxRQAd6KWkoAKSlIPejFACUUUUCCiiimAUHk9MUrYHTpSUhBRRgiimAlFLRQAlFLikoAKKKKAEpwBYgDqaSjvQAEEHBop5QBgGbg9TTDjJx0oEFJS0UDCikpaACiiigApSCOtOjKg5YZHpTSc0CEooooGBAB4OaPoKUkE8DApOaACkpelHagBKXBxnHFFGSBjtQAlFLSUAFFFFAARjvRRSk7jk9aAEooooAKKXHGc/hQBk4HU0AJQRigggkHrTs5XBPTpQA2ijBooASilpKBhRRRQAUUUUAFJS0DHc0CEooooGGKKKKACiiigAoxSUuaAEpcZ6UlKCRnFACUUUUDEopaKAEopaKAEooooAKKKKAEopaKBiUYxRRQAUUUUAFJS0UAJRRRQAUUUUAFFFKATwBQAlFFFMYUlLSUgCil5xRQAlFFLxj3oASiilxmgBOcZoPNFFABRRRQAYoooyTj2oAKfuGKZ344qTYuBxzQAxWAJzSsQelCqDQy46UDF3DFNUgZzTtoxTVGTQIViD0pQwxTXAHSm0AB61NZ/wDH7b/9dF/nUNTWf/H7b/8AXRf50PYZcu/+P2f/AK6N/Ooamu/+P2f/AK6N/OoxULYoQCkIpc0lMLijinA5NMpcYNAEoIIoNMB5pxapGGacKYKeKBC0UUUDExSrRijFACsOOKhxzzUvWkxQhMaFpdvNPApcZouMiKZo8upcUEUXAh29qTaakI5pwGadxWIwtGKlxSYpXFYjop+KXGaLiEUetO/lQM0uKQxMUYGKdjtS4oAjI/Gm4/OpaCKdwIcYNLjOe1PK+nSmEGgQlA4460vUe9FMBOlJindvaj6UANx0FJTyuKTHNAhuKMU4+lGKAGEUFeKdQR1z96gBvFJT8UYoAQA44pADnjrUgIA5poPzE4oAawPelAbHHSnMQRxzQCAOaAIxkN70rg45707PzZpWII4oAYA2OKbyDUikYpp5NO4DSSetAYgUuKMUCG0U7FGKAG4Iop1JQAlFLiimAlFFFABjPA60AHPI6daM4PFGTzz1oEJ3opaSgYuKSlowcZ7UAAxzkZ9KKXGTRSEFJS9qKAFdy/XHFMNKaOtMBD0pO1LRQAlLxg5P0opKBBRR16UUwENLRRQAUowTg9e1JQODkUhAcg4NFB5OTQRg4NMBKKKKAFpKKKACg0UUAOKYQNkYNNpTSUgCjFFKCR0NMBKKKKACiiigApzAA8HNNpdpChuxpAGfk24GKSilpgAUtnA6daQU7ceeevXFNoAOcUCiigA7UlLRQAlFLx36Urbdx28CgBtKxyc4ApKKAClpKWgAoBxyOtFJQAUUdqKAFxx1pKKKACkpaKAEpWAB4/WijP40AIMZ56UUUUDCiiigBKKWkoAKKKKACijBxntRQAUUUUAFFJS9qAEoopaAEoopTxkA8UDEoooxzzQAUlKevHSigA70E5PpSUUAFFFHNACUUtFAwJ4x2pKUDPFFAhKKKKBhRRRQAlFLRTASgEilopAJRRRQAUUUUDCiiigBKKKWgAopKKAClpKO2KACiiigA7GgUUY4z2oAKUuxpKO9AwBx0o3ZPNBxnjpSYoAXcelAJHSkooAUnNJRRQAVNZ/8f0H/AF0X+dQ1NZ/8ftv/ANdF/nQ9gLl3/wAfs+P+ejfzqH2qe7/4/Z/+ujfzqHgn6VC2GAoxS0UwAKe1LtOKcnSnkcUrjIaWpAlIVyaAGU4HFG3mjaR1oAcGFLkVH0GaUGkA/NLTB1p3agLi4peKAM8UZ/KkAtFJS5HagA6UlHvnNHXmgBaAM0UooAXHpTelPBI5B5pp6UANxRjml5NJ1oEKBzkdKUelAAOPWjpQAvXA70vaijrQMOtHUUpIOO2KVdvO/p2pAMx6Um3NKRikyaYhjKQaMZ7U+j+dFwIz9KMZFPHByOlN6fSmIMZPFJin4ZVB7HpTSMe+aAGkUcD/ABp3t2pMelADcetH86djijHPSmITBxRgUvTPNHakAgUYJ6U5NpcFhxikoAJPAoAV1GCcYpFUYz19qVlI6nNChuoNAAqjfj2pJFAHHFHOehzQwbHNMBmKO+cUtGOfagBuKMU9lAYDOR3NNIGeKAExSU4gZ6cUdKAG4oxTiMcUlAhuKMU6kxTAbRinEUmKAG0UuKKYCUUtFAhKXJxjPFBGKUgA8HNIBKKKKBhRRRTEGKQjHfNFFABSUtFAgYg4wMU2looASilpMUAFFFFABRxnpRR0ODTEFJS0UAJRS0UAJRS0D6UAJRS9qSgA60UoGQT6UUAJRS4pMYoAUHGeM0E57UlFIAoopeMdOaYCUvJ4oAyRnpTnQD7rAikAyiiimAUUtBxnjpQAlFFFABRRRQAUUUUAJS0UGgAxRRRQAUlLRQAlKRjGDmiigBMUUuBjrzShd7cYFIBtFLSUwCkpaKBiYopaKAEopaSgAooooAKSlooAVSO/Sm04tkAYxim0AFFFFAAQR1pQAQc9aMnbjtQCRn3oASiiigApKWigAooooASlo4zzSUDCiiigAooooASiiigBQMnGcUnQ0UUAFJS0lAwopRxSY4zQAUUUUAFFBGOtFACUU4IWBIxxTaACiiigAooooAUMQCMCm0tFAxKKWimAlFLRSASiilxTASiiikAUvGKSigByAEnNDjHSm0UDEpaKKACiiigBKns/+P23/wCui/zqGprP/j+t/wDrov8AOk9gLl2R9tn/AOujfzqHOe1T3Wftk+B1kb+dRbTUrYGIKKdgd6cMYoGAGKd60lKADSGLyQOaPagflS49qBiAUY56UuKcB3pCIivNIf0qYgCozz06U0wGZ596dnBpMY7UvamIVTTs4HFNHGKXPHFIYHmgHik4/wAKXrxQAtH0o6+9ApCFz6UDr9aTPPTHtSjrQA7ORSf5NGfyooAMd6XH/wBak/lR6HmgBe1Ljmkpc0AJThjBOfwpPaigBfrSfzoOelLxigY31z+VJggU7inAcdaBDVAP3s+2KTn608/Tg03uaQxv60N144p2O+KTAx7UxDDn3+lGPWpFzjYO9EkZj6nPpRcLEZ/Sk7YIpxH5Uh5xTEJ1PTmilHWg0AJRx0NL3wetKoUZ3DPpQIaetKpwcijB6mhVyaAHZViAeFoyFO3tQ6jGad1HNAEe7Dc0rN8uKAPnxmlZRjgdKAIvxoxS/TkUdT7UAJjj2opfrQB7UwG4o6cU7FIaAE49M0lO/GkoASjFOxz0pMUANxRS0UANIoxTqTAxQIbj1oxTqKYDKKdikxQITFApcUuKAG0UuKMUAJRRRTASilpKBBSUtFACUUtJQAUlLRQIAcHPpQTuJJ6mikoAKOlLRQAnWloooASilpKACilPPNGKAEopaSgAopT1pKACilpKYB2FFFFABRRS4460gE7UUtJQAUUUY/KgAooooAKSlopgJS8UUUDEopaKBCYoopaAEoAJzxRS80hiUtFOAoAbijFP28UEUDGYpMU/FIRxQAyilpKYhKWiigAzQevWijBJ4oASiiigAooooAKKKKACkpaKBiUUUoBNAhKKKKACiiigAAOKDjHTmlBI6d6SgBKKWigYdqSlooATFFLRQAlJS0UAJiilpeNvvQA2jFLSUDCkpaKAEopaKAEJJo4peMUlABQAMHP4UUYxQAUlLRQAUUUUAJRSgZNHSgBKKKMUAFFFFAwooooAKKKM8HigBKKKKACiiigAooooAKKKKAAAnpU1n/x+wf8AXRf51DU1n/x+wf8AXRf50PYaNC6H+mT/APXRv51F1B54qW6yb2f/AK6N/Oojg1mhie1LRtPrR9RTAX8eaX3oxk8d6cAF56mkMFHc9KcGAbIpvJ57Ucg470gHYpelN5HWjJ+tAAfQUmPelPfjim+/egAPPPrTM4oJ7YpDntVCFzx7Uv8An6UnNKFPGBQAo6dPxoPBp6rg04pntU3GRjnpTqUrijHNFwEwT35pD6AdKXB/ClwOlArCfSj+dKAT24pwjLHngUXCw3AzS8mpFj9+aeFC9OKXMOxEEYj0FPCc808U8AYzUuQ1EgZMHikKnPWrBWmMPyoUgcSHac0nI6VIR37U0g596q4huMfWkHGf1pT7UnFMQowQOacT0qPHenKpz1/+tSHcUjn39KPQmnYIJAOfem45JoAQEg5HWhyzHmnHKjBHBpp9KBDMc470DgU7GKPwpiG9BRinEAn5f1pPw6UAIf0ox6U4jmgryQOlACEjAx170gU9qX8KM4PrQICMDnmlAO2gt7UBu2ORQAzBzxTmDdaOjZpzEnpTAjCnFGMHBqVCpB3dqjznrQA00uMYx0oOM0HigBO9AHHtRjmlydpUcgmgBoxnJGRQR+VLj86TjtQAmM0fSlIo9+9AgPJ7U3HNO4zSeo7CmAmKSnckUUANxSYpwGf8KMd6AG0U7bx70lACY4pMU7FJTATFGMmlo5oENopaMUAIRSU73pMUCEoxS4o4oAbRS0UAJSU6igBtFLiimISjFLilAyaADbxmm0tFACdqO3vS4pQpPSgBvSlGO9FGKAEoxRS0AJQcUpFAODmgBDRSnBOQMUYGeaAE60UDiigAooooAKKKKADpRziijHFABiiiigBKKWigBKKUnjb2pKACiiigAoo70UAFFGKUUAKKljUntUQFWYTikxkiw7TnGaiePb0q4HXbVaUjmpi3cppJFUim04001YhtFLSUxBijHGaKKAEopc8YxSUAFJS0UAJRRRQAUUUUAFFFFABRRRQMKSlooEJRRS0AJRRRQAUUUUAFBxniigjFAB06Ud6DjjFBBA5oASloooGJRRRQAUUUUAFFFFACEUuBtznn0pD1ooAKKKKACg8nn86KKBiUUUUAFFFFABRRRQAUlLRQAlFLRQAg680Hg0UUAFFFFAwoooPFABSUtGKAEopcUDGeaYCUuPlzmkopAFT2n/H9b4/56L/OoKms/wDj9g/66L/Oh7AjRu/+Pyf/AK6N/OocZqzdqDeT84/eN/OoQlZJ6FjQM96cMDr0p3l0BMc0XCwY/AU3vilcZIHak578CgAzk4704c9KTBx0pwGKAFA46c0n40pHOKMc/SkAzvikOKdjIwOlKqAdeadwGhcjIHB605YyTn9Kd9BThxzSbHYFjUdBSlaeMdhSj3qWyrDAvPSgpUmKBgUrhYi20bfapTikzRcLEflk4zxTvKAPrUnHpS/hRcLEe0DtR1px+tAFFwsIB70Ec+1Px7UhHtSuFhAMU8dKTHejOKGNKw4c+1MJHfignFNJ46c+tCQmxDTSp60uc0uaokYV70bR1p+RRxRcLDDHtHNGMVKhVScjOaTZzRcLEWfwFHLHpUjKM0qjB6UXCwwITx+tL5THmpckCnbvzqblqKIBDxzSiH8qm4pSaOZhyohMQ+lIUUDHWpj0pu2i4cpXI5OBQVHGCSe9WdgFLtHpT5hchU2nFJirRTNMMeafMS4FfH51IoG0U8xNjNAgJzng9qfMhcrIQBu9qVgMZxUy2xY8mpPswAyTmjmQcjKm09+gppHH8hVwxDGAKrspDdKFK4SjYiwCaOCCaexBbIGKbjtVECdMUnQ5FP2k8UhGOaAG4544zSkYO3vRjjnpRQAh680mKXt9e1GO5pgJ3NFL1OOlJ2oAQ0UvSjHr0oEJjmk7Y7U4Dn2o68+nagBtJ1p3UdKKYDevWjoc+lLRj1oATAJ54FIR707rx2oI5oAYaMU7HrRjuaBDMUU7FGKAG0lOoBI7UxDaKXFJQAUUtJQAUYoooAMcZpMUtFABRRRQAmMUvTilH50lACYopTR3oAQ0lOIxSUxB1pKWigAwcUhGKWjGKAExRS0lABRS0UAJRilooAbRTulJQAlL296KMcUAGMEZpKKKADvR0oooASjFLRQAcbe+aSlooAARzxRRRQAoqVHCA8Zz0qLgdDS44z2pDJvNP1qNn3Gmk0hHy5zRYAzzSHg4HNFJTAKSlpKYgooooAKSlooASjHGc0vU0lABRRRQMSilooAT60YzRS0AHXoKSlBI6GkxQAUUpGOKTpQAUZoooAKSlpKAFBwc0MCDkjGaSjNABSkk4z2pKKACgknvRRQAUlLRQAlFLRQAlFFFABRRRQMKMUUUAFFLgbc559KSgABKnI60E7jk0YooAbS0UUAFJS0UDEopaSgAopaSgAopcUlABRRRQAUAE/hRSZoAKKU5A+tJQAUUUlAwzRRRTAKKKWkAlTWf/H7b/wDXRf51DU1n/wAftv8A9dF/nQ9gRsXQ/wBMmyP+WjfzqLANXLtR9sm7fvG/nUOwHiuZM1cSHB7UoLDtT/LI5BoAI4Ip3CwzAPUU7yxT9oPak2kdDSuFhrR4PBBphU5xUuSOo/KnZRhii4WK/IFAHzfN+dTFB65ppjIHtVXFYZ2x2pDyadjmm460AKOTmnAUxSefWnA8UASL0OacME4JwO1RZ96Cc0h3H5pN3NJ160mfaiwmx+cjmjdjmmg++KO1AXJQ1G7iouelBNKw+YecZznNKGFRZNLup2FzExPHWjPPXrUOcmlDEUrD5ib2oNRb6cH9RRYfMOxTCD60u7NGaBDSppOcY/Gn9s02mAnbpQPvY70HpSAE0CJB696eMkZFRjJPPFP59aTGhp9qUUuOKMUAGaUGkIpMUh3H0tMBIpwJxSGmO6UYpM06kVcMUYpe1LQMTFGBTqKQxuBS4oooABwc0rNkUlFMBKZIDtIFThRimhRuIPShMTVzPYEdRTccEVoyQhl9KrNbEcg1opGLgyBTt60rEcdxSmFhyKQqRyaq5FmMxzSYPAp5HWm+xpiE7+9H607Gfc+lJjt37g0AJjj3pCPzpe/FB5Oe9ABSYpT1oI9KYCDp0oxxxS49+tJgjp0oATrxnmgj3pcdaKBCfWk9qcefekoAT+dGKUelFACY5pCKf8uz/apP0oAbjml2jucZpT9MUmOuaAGkUmPXpTu1GKYhhFHtTgMkD1pCuDigQ2jkU6kxTASilxxRQAmKCKXHNGKAEopxGDjNGBj3oAbRjPQUtGSeKAEpKWjFACUUtFACYooooAMUGiloENxS0tFACUuOOvNLyetOC8UAMxRjHSpdnr0oMdK4EOKCKlKUjjmncCLFGKeRTSKAG4op1JRcBKKXFFMBtKeaKUcmgBtFLiigBKKXFJQAUuaSlxQAE0UUlABRRRQAlFLSUAFJS0UAJRS4ooATpzR1OKWigBCMHFGKKKAEopaKAEopcUYoASkpwBOcUlAxKKWigBKKWjFACUUUUwCiiigBMUUtFACUUtFACUUtBGD1zQMSiiigQEYODRRRQMDj0xSUtFABikpaKAEpQCTgUlFABRRS5OMetACUZyAPSiikAUUUUwCkpaSgAowcfWiigYUlLRQAlFL2pKADFFFFABSYpaKAEopaSgBQSDn0pAMn0opSAOhzQAh60H2oopjEqez/AOP2D/rov86iUgHkZFS2f/H9B/10X+dJgjfuf+Pub/ro386iqW5z9rm/32/nUYrkNxRTsZ60gpRSKEK56Gm7TUlA5ouFhmDjpUZQE8cVP9aKdwcSuEbNO6cEHNS4o4xg0XJ5SIqD1prJ6VMY8cqePSmdOO9O4NEBU5zQQRxU+Ae1Js/GncmxBnBozzxUjJ14phTAzmqTE7gD+dJmjB7mlwMZoEHQZxSg5NN5xQeBQIfz3pMUgx1xgUoxnnigYEUdDRSc5oEHal7UnT/PSjjtQAYxSgk8UYHTril647UAGf8A9VSDpzUYHPvTxj8aTKQrHpTTk0rcim55oBiU4dPSkxS55FAD1FSAcU1cU8CoZpETFGPSlpckcigY3FJjmlNLQKwgXPFLilpM0DsCqTQQQcGlVsHNDEk80AGOKTNGfSjPagVxwPFOzUf1pwpWKTHUUCjNIYUYpdtLigYnOODS0UUhC5NHWkpc0DEKj0prRowxin0Yp3CxWaFD7VWkiK8Z4q+65xVaRWYknmtIyMZxKoyCP0pTkEhutOKnPK/Sm4/H3NaGQhxjAox0zS9v5UnSgQH9KTtR9adgEjHy8fnTAbmjpS/Wjv6ikAhA9aOe1HQ0vagBKTrS+1GBQAGkH60vHA/nR1oAT3opTx1/GigBMc80lOx+FB5FAhvU5pMU7Ge1H8qYDSOtJin7eM84ptACY70mKd0+lLjJoEMxxSU/BxnHFJTAbijFOpMUAJig0uKPegBOtB4FL7UdTQIQe1JTjz2xRwOnWgBppKdijFMBMUlO7UYx2oAUJxSEYOKeGFNPJpCG470opcU7GcUACrk4HWpEjJNSIgBHrU6RipbKSuReVxS+VmrIQYpSg7VHMaKkym0fBqNo8GrxTAqJl46U1ImUWiiV5qMirLoc+1QsuK0TIIqKdSUxDaKXFFACUdKKWgBKKKMYoASilxRigBKKXFGKAEopcZOKQ9aADHGf0pKUjjNHamAlFFFABRRRQAUUlFABRRS44oASjFFAJHSgBMUUtJQAUpx2pKKAAEjpRRRQAlFLSUDCiiigAooooAKOtFAJHSgBKKWkpgFGaCSTk0UgCkpaSgAooopgFFFFABRRRQMSiloPNABSUuKTFABRS0lABRRRQAUUtJQAUUUo68jNACUlLS7htxgfWgBBjBz17UlL29qCMUAJRRRQMKASpyKKKAEopaSgAoopccf0oAbS0YwfeigApKUUdDQAlWLID7ZBnr5i4/OoDU1n/wAfsH/XRf50nsM37n/j7m/66N/Oo/X0qzcW1x9rmIgkwXb+A+tR/Zbj/nhL/wB8GuS50kYzRUotbj/nhL/3waPstx/zwl/74NAEdFSfZrjP+ol/74NL9muP+eEv/fBoAjzRUgtrj/nhL/3waX7Ncf8APCX/AL4NIZFmkqb7Lcf88Jf++DSfZbj/AJ4S/wDfBouIioIBGDU32a4/54S/98Gj7Ncf88Jf++DRcCvsIPB49KATtxjBqf7Lcf8APCX/AL4NH2Wc/wDLCX/vg07isQEZ61GyVa+yXH/PCX/vg0fZrj/nhL/3waaYrFJkz2qM5FX2s7g/8sJf++DURs7gj/j3lz/uGqUiGmVd3GfWipWs7kHPkS4/3DSC1uf+feX/AL4NXdEjM9KKk+y3H/PvL/3waX7LckD9xLn/AHDS0AizS54681J9luP+feX/AL4NJ9luf+feX/vg0aARjrTu/T8af9kuAP8Aj3lz/uGlFrcgcwy/98GgCMdM0ZPapPstz/zwlz/uGl+y3H/PCX/vg0aARL6U7rTxa3H/ADwlz/uGl+zXHa3l/wC+DSGMB9aQjBqb7Lcf88Jf++DSi1nz80EuP9w0XGV85/CnBqebS5x/qJf++DR9luccQS+3yGjQQ0HnNSBuaRbW4z/qJf8Avg08Wtxn/US/98Gk7FJi5yOOtJnFPW2uB/ywlH/ADS/Zbgj/AFEv/fBqS7kVKKk+zT/88Jf++DSi1uP+eEv/AHwaAIs0h5qb7PcYINvJ/wB8GkFtcf8APCX/AL4NAMjFB6VL9luf+eEmP9w0n2a4PSCX/vg0ARinACni1n/54S/98GnfZbjH+ol/74NIEiOjB7VL9ln/AOeEv/fBoFtcY/1Ev/fBouVYi7Uo96l+zXH/ADwl/wC+DR9mn/54S/8AfBpANBop32a4/wCeEn/fBo+zXH/PCX/vg0DuMzS5pfs9wOkEv/fBpfs9x/zwl/74NAXGUo4p32a4/wCeMv8A3waUW9x/zwl/74NADaKk+zz/APPCT/vg0v2af/nhJ/3waVxkRFNKA9qsfZp8f6iT/vg0n2af/nhJ/wB8mi4FNosng1C8LDpzWibWf/nhL/3wab9ln/54Sf8AfBqlIhwTMsr2xik2Z4HNaD2U5z+4k/74NQGyuP8An3lGP9g1opGThYqlT35pvNWzbXGP+PeX6bDTTZ3Gf9RL/wB8Gq5iGitjjmjoOO/WrBtLn/nhKR/uGkNpcY/495R9ENF0FmV/oaXuPSp2tbh8f6NKMf7BpDaXP/PCX/vg0XQrEJoPHSphaXJbBt5f++DStZXKNtMEpJ77DTuh2IOKKl+yXJP/AB7y8f7Bo+y3P/PvL/3waLhYh+v5UvXrUv2S4PH2eX/vg0fZLjnEEv8A3waLisQ9aMc1MLW4/wCfeX/vg0fZbn/n3l/74NFwsQ/jSdan+yXA4+zy/wDfBo+yXH/PCX/vg0XQWIATjGePSgdc1N9kuM/8e8v/AHwaPslx2gl/74NFwsQcU4AFWHfqDUv2W4H/AC7y/wDfBoNpc4x9nl/74NFxEGeOvHpSYxVgWtyAR9nl5/2DSfZLn/n3l+uw0XQEGKDU/wBkuev2eX/vg0fZLj/n3l/74NFwK5oqf7Hcf8+8v/fBoFpcd7eX2+Q07hYgx69KO+KsfZLn/nhL/wB8Gk+yXP8Az7y/98Gi4WZBgikqwbS5J4t5f++DSfZLk/8ALvL/AN8Gi6FYgx270hGKsfZLnj/R5f8Avg0fY7jB/wBHl/74NF0FiCjB71N9kucf8e8v/fBo+yXOf+PeX/vg0XQWIR60VP8AZLn/AJ95f++DSi0uP+feX/vg0XQrEOKegAOD0qQWdx/z7y/98GpFtLjvby4/3DSuh2HRrgVYRec02O2uOnkS/XYasLbT5z5Ev/fBrOTNaaG0YqX7NP8A88Jf++DS/Zrj/nhJ/wB8GoudFiDFROMGrn2af/nhJ/3waie1uM/6iT/vg00zOotDPkHB9arkc+/cVova3O0jyJP++DVdrS4/595ff5DWqZzNFIjn2ppFWTaXJP8Ax7y/98Gm/ZLn/n3l/wC+DV3FYr4oxzU/2S5/595f++DSfZLkHIt5f++DRdBZkJUjrSVYNrdOf+PeUf8AADTfslz/AM+8v/fBouFmQ0VP9kuf+feX/vg0n2S5/wCfeX/vg0XQWIaKm+yXP/PvL/3waPslz/z7y/8AfBougsQ9KKnNpc55t5c/7hpPslz/AM+8v/fBougsQUVY+yXI5+zy/wDfBpPslz/z7y/98Gi6CxXoqf7Jc/8APvL/AN8Gj7Jc/wDPvL/3wad0Igoqf7Jc/wDPvL/3waPsdz/z7y/98Gi6AgpKsfY7n/n3l/74NJ9kuf8An3l/74NF0FiCip/sdz/z7y/98Gj7Jc/8+8v/AHwaLoLEFFT/AGS5/wCfeX/vg0fZLn/n3l/74NF0FiAgikqc2lz/AM+8v/fBo+yXP/PvL/3waLoCCipvslz/AM+8v/fBo+yXP/PvL/3waLoCGkqf7Jc/8+8v/fBo+yXP/PvL/wB8Gi4EFFT/AGS5/wCfeX/vg0fZLn/n3l/74NFwsQUAc+lTfZLn/n3l/wC+DR9kuf8An3l/74NO6CxCeCQORRU/2O5/595f++DSfZLn/n3l/wC+DRdDIMUVP9juf+feX/vg0fY7n/n3l/74NF0FiCip/sdz/wA+83/fBpPsdz/z7y/98Gi6CxDRU32S5/595f8Avg0fY7n/AJ95f++DRcCGkqf7Hc/8+8v/AHwaPslz/wA+83/fBougIKKsCyuT/wAsJR/wA0n2O5/595v++DRdAQUVN9juf+feb/vg0v2O5/595v8Avg0XQ7Feip/sdz/z7y/98Gj7Hc/8+8v/AHwaLoLEFFT/AGO5/wCfeX/vg0fZLn/n3l/74NF0FiCipvsdz/z7y/8AfBo+x3P/AD7y/wDfBougsQ0VP9kuf+feX/vg0n2O6/59pv8Avg0XQWIaKn+x3X/PtN/3waT7Hc/8+83/AHwaLoLENFTfZLn/AJ95v++DR9juf+feb/vg0XQENJU/2O6/59pf++DS/Y7r/n2m/wC+DRdAQAEjjtSVYFrdAcW83/fBpPsdz/z7S/8AfBougsQUVYFndE4+zy/98Gk+x3P/AD7y/wDfBouhkGTjGeKKn+x3P/PvL/3waT7Hc/8APvN/3waLoLENFTfY7n/n3m/74NH2O5/595v++DRdBYhoqb7Hc/8APvN/3waPslz/AM+03/fBougsQUuKm+x3P/PvN/3waPslz/z7Tf8AfBougIKKn+x3P/PvN/3waPsdz/z7Tf8AfBougIKKn+x3P/PtN/3waPsdz/z7zf8AfBouhkFJU/2O5/59pv8Avg0psroHBt5T/wAANF0BBU1n/wAfsH/XRf50fZLn/n2m/wC+DUtpa3IvICbeUYkXnYfWhgkf/9k=');
    }
    .boxPadd {
        padding: 5px 10px;
    }
    /deep/.u-line-progress__text {
        color: #000 !important;
    }
    /deep/.u-radio-group--row {
        justify-content: center;
    }
    .ridoa {
        text-align: center;
        padding: 10px 0px;
    }
    /deep/.placeholderColor {
        color: #fff;
    }
    /deep/.u-form {
        display: flex;
        justify-content: space-evenly;
    }
    .slot-content {
        width: 80%;
    }
    /deep/.u-cell__body,
    /deep/.u-cell__title-text,
    /deep/.u-cell__value {
        color: #fff !important;
    }
    .ridioBox {
        margin-bottom: 10px;
    }
</style>
pages/actionChange/secondLevelData/parameter.json
New file
@@ -0,0 +1,44 @@
{
    "flylon": "经度",
    "a00e12": "光照强度",
    "a00e34": "TSP",
    "a00e13": "噪音",
    "a21005": "一氧化碳",
    "a21004": "二氧化氮",
    "a21026": "二氧化硫",
    "a21028": "硫化氢",
    "flyhig": "高度",
    "a21001": "氨气",
    "a40002": "苯乙烯",
    "a21022": "氯气",
    "a00e19": "二氧化碳",
    "a40001": "烟气流量",
    "a01001": "温度",
    "a25005": "二甲苯",
    "a05024": "臭氧",
    "a21024": "氯化氢",
    "a40003": "环氧乙烷",
    "a25003": "甲苯",
    "a01002": "湿度",
    "a25002": "苯",
    "a23001": "酚类",
    "a01007": "风速",
    "a01006": "气压",
    "a01008": "风向",
    "a30001": "甲醇",
    "a19002": "臭气浓度",
    "a19001": "氧气",
    "a34002": "PM10",
    "a34004": "PM2.5",
    "dustld": "尘负荷",
    "PORRST": "开机标识",
    "a00e03": "颗粒物0.3",
    "a00e04": "颗粒物2.5",
    "a06001": "雨量",
    "a99054": "TVOC",
    "a35e21": "核辐射",
    "a01011": "烟气流速",
    "a24088": "非甲烷总烃",
    "flylat": "纬度",
    "a31001": "甲醛"
}
pages/login/login.vue
@@ -29,6 +29,7 @@
                <u-button @click="submit">登录</u-button>
            </view>
        </view>
        <ws-wx-privacy id="privacy-popup" enableAutoProtocol></ws-wx-privacy>
    </view>
</template>
<script>
@@ -44,6 +45,7 @@
    export default {
        data() {
            return {
                titlePrivacy: '用户隐私保护提示',
                labelStyle: {
                    color: '#fff'
                },
@@ -81,9 +83,23 @@
            uni.hideHomeButton()
        },
        methods: {
            doRequire() {
                uni.requirePrivacyAuthorize({
                    success: () => {
                        console.log('同意')
                        // 用户同意授权
                        // 继续小程序逻辑
                        this.getlogin()
                    },
                    fail: () => {
                        console.log('拒绝')
                    }, // 用户拒绝授权
                    complete: () => {}
                })
            },
            submit() {
                this.$refs.uForm.validate().then(res => {
                    this.getlogin()
                    this.doRequire()
                }).catch(errors => {})
            },
            //登录
static/img/headSculpture.png
Binary files differ
static/img/shouye.png
Binary files differ
static/img/shouyeClick.png
Binary files differ
static/img/wode-.png
Binary files differ
static/img/wodeClick.png
Binary files differ
static/img/xinjian.png
Binary files differ
static/img/xinjianClick.png
Binary files differ
uni_modules/uni-popup/changelog.md
New file
@@ -0,0 +1,68 @@
## 1.8.3(2023-04-17)
- 修复 uni-popup 重复打开时的 bug
## 1.8.2(2023-02-02)
- uni-popup-dialog 组件新增 inputType 属性
## 1.8.1(2022-12-01)
- 修复 nvue 下 v-show 报错
## 1.8.0(2022-11-29)
- 优化 主题样式
## 1.7.9(2022-04-02)
- 修复 弹出层内部无法滚动的bug
## 1.7.8(2022-03-28)
- 修复 小程序中高度错误的bug
## 1.7.7(2022-03-17)
- 修复 快速调用open出现问题的Bug
## 1.7.6(2022-02-14)
- 修复 safeArea 属性不能设置为false的bug
## 1.7.5(2022-01-19)
- 修复 isMaskClick 失效的bug
## 1.7.4(2022-01-19)
- 新增 cancelText \ confirmText 属性 ,可自定义文本
- 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
- 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
## 1.7.3(2022-01-13)
- 修复 设置 safeArea 属性不生效的bug
## 1.7.2(2021-11-26)
- 优化 组件示例
## 1.7.1(2021-11-26)
- 修复 vuedoc 文字错误
## 1.7.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-popup](https://uniapp.dcloud.io/component/uniui/uni-popup)
## 1.6.2(2021-08-24)
- 新增 支持国际化
## 1.6.1(2021-07-30)
- 优化 vue3下事件警告的问题
## 1.6.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.5.0(2021-06-23)
- 新增 mask-click 遮罩层点击事件
## 1.4.5(2021-06-22)
- 修复 nvue 平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
## 1.4.4(2021-06-18)
- 修复 H5平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
## 1.4.3(2021-06-08)
- 修复 错误的 watch 字段
- 修复 safeArea 属性不生效的问题
- 修复 点击内容,再点击遮罩无法关闭的Bug
## 1.4.2(2021-05-12)
- 新增 组件示例地址
## 1.4.1(2021-04-29)
- 修复 组件内放置 input 、textarea 组件,无法聚焦的问题
## 1.4.0 (2021-04-29)
- 新增 type 属性的 left\right 值,支持左右弹出
- 新增 open(String:type) 方法参数 ,可以省略 type 属性 ,直接传入类型打开指定弹窗
- 新增 backgroundColor 属性,可定义主窗口背景色,默认不显示背景色
- 新增 safeArea 属性,是否适配底部安全区
- 修复 App\h5\微信小程序底部安全区占位不对的Bug
- 修复 App 端弹出等待的Bug
- 优化 提升低配设备性能,优化动画卡顿问题
- 优化 更简单的组件自定义方式
## 1.2.9(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.2.8(2021-02-05)
- 调整为uni_modules目录规范
## 1.2.7(2021-02-05)
- 调整为uni_modules目录规范
- 新增 支持 PC 端
- 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端
uni_modules/uni-popup/components/uni-popup-dialog/keypress.js
New file
@@ -0,0 +1,45 @@
// #ifdef H5
export default {
  name: 'Keypress',
  props: {
    disable: {
      type: Boolean,
      default: false
    }
  },
  mounted () {
    const keyNames = {
      esc: ['Esc', 'Escape'],
      tab: 'Tab',
      enter: 'Enter',
      space: [' ', 'Spacebar'],
      up: ['Up', 'ArrowUp'],
      left: ['Left', 'ArrowLeft'],
      right: ['Right', 'ArrowRight'],
      down: ['Down', 'ArrowDown'],
      delete: ['Backspace', 'Delete', 'Del']
    }
    const listener = ($event) => {
      if (this.disable) {
        return
      }
      const keyName = Object.keys(keyNames).find(key => {
        const keyName = $event.key
        const value = keyNames[key]
        return value === keyName || (Array.isArray(value) && value.includes(keyName))
      })
      if (keyName) {
        // 避免和其他按键事件冲突
        setTimeout(() => {
          this.$emit(keyName, {})
        }, 0)
      }
    }
    document.addEventListener('keyup', listener)
    this.$once('hook:beforeDestroy', () => {
      document.removeEventListener('keyup', listener)
    })
  },
    render: () => {}
}
// #endif
uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue
New file
@@ -0,0 +1,275 @@
<template>
    <view class="uni-popup-dialog">
        <view class="uni-dialog-title">
            <text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{titleText}}</text>
        </view>
        <view v-if="mode === 'base'" class="uni-dialog-content">
            <slot>
                <text class="uni-dialog-content-text">{{content}}</text>
            </slot>
        </view>
        <view v-else class="uni-dialog-content">
            <slot>
                <input class="uni-dialog-input" v-model="val" :type="inputType" :placeholder="placeholderText" :focus="focus" >
            </slot>
        </view>
        <view class="uni-dialog-button-group">
            <view class="uni-dialog-button" @click="closeDialog">
                <text class="uni-dialog-button-text">{{closeText}}</text>
            </view>
            <view class="uni-dialog-button uni-border-left" @click="onOk">
                <text class="uni-dialog-button-text uni-button-color">{{okText}}</text>
            </view>
        </view>
    </view>
</template>
<script>
    import popup from '../uni-popup/popup.js'
    import {
    initVueI18n
    } from '@dcloudio/uni-i18n'
    import messages from '../uni-popup/i18n/index.js'
    const {    t } = initVueI18n(messages)
    /**
     * PopUp 弹出层-对话框样式
     * @description 弹出层-对话框样式
     * @tutorial https://ext.dcloud.net.cn/plugin?id=329
     * @property {String} value input 模式下的默认值
     * @property {String} placeholder input 模式下输入提示
     * @property {String} type = [success|warning|info|error] 主题样式
     *  @value success 成功
     *     @value warning 提示
     *     @value info 消息
     *     @value error 错误
     * @property {String} mode = [base|input] 模式、
     *     @value base 基础对话框
     *     @value input 可输入对话框
     * @property {String} content 对话框内容
     * @property {Boolean} beforeClose 是否拦截取消事件
     * @event {Function} confirm 点击确认按钮触发
     * @event {Function} close 点击取消按钮触发
     */
    export default {
        name: "uniPopupDialog",
        mixins: [popup],
        emits:['confirm','close'],
        props: {
            inputType:{
                type: String,
                default: 'text'
            },
            value: {
                type: [String, Number],
                default: ''
            },
            placeholder: {
                type: [String, Number],
                default: ''
            },
            type: {
                type: String,
                default: 'error'
            },
            mode: {
                type: String,
                default: 'base'
            },
            title: {
                type: String,
                default: ''
            },
            content: {
                type: String,
                default: ''
            },
            beforeClose: {
                type: Boolean,
                default: false
            },
            cancelText:{
                type: String,
                default: ''
            },
            confirmText:{
                type: String,
                default: ''
            }
        },
        data() {
            return {
                dialogType: 'error',
                focus: false,
                val: ""
            }
        },
        computed: {
            okText() {
                return this.confirmText || t("uni-popup.ok")
            },
            closeText() {
                return this.cancelText || t("uni-popup.cancel")
            },
            placeholderText() {
                return this.placeholder || t("uni-popup.placeholder")
            },
            titleText() {
                return this.title || t("uni-popup.title")
            }
        },
        watch: {
            type(val) {
                this.dialogType = val
            },
            mode(val) {
                if (val === 'input') {
                    this.dialogType = 'info'
                }
            },
            value(val) {
                this.val = val
            }
        },
        created() {
            // 对话框遮罩不可点击
            this.popup.disableMask()
            // this.popup.closeMask()
            if (this.mode === 'input') {
                this.dialogType = 'info'
                this.val = this.value
            } else {
                this.dialogType = this.type
            }
        },
        mounted() {
            this.focus = true
        },
        methods: {
            /**
             * 点击确认按钮
             */
            onOk() {
                if (this.mode === 'input'){
                    this.$emit('confirm', this.val)
                }else{
                    this.$emit('confirm')
                }
                if(this.beforeClose) return
                this.popup.close()
            },
            /**
             * 点击取消按钮
             */
            closeDialog() {
                this.$emit('close')
                if(this.beforeClose) return
                this.popup.close()
            },
            close(){
                this.popup.close()
            }
        }
    }
</script>
<style lang="scss" >
    .uni-popup-dialog {
        width: 300px;
        border-radius: 11px;
        background-color: #fff;
    }
    .uni-dialog-title {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
        justify-content: center;
        padding-top: 25px;
    }
    .uni-dialog-title-text {
        font-size: 16px;
        font-weight: 500;
    }
    .uni-dialog-content {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
        justify-content: center;
        align-items: center;
        padding: 20px;
    }
    .uni-dialog-content-text {
        font-size: 14px;
        color: #6C6C6C;
    }
    .uni-dialog-button-group {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
        border-top-color: #f5f5f5;
        border-top-style: solid;
        border-top-width: 1px;
    }
    .uni-dialog-button {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex: 1;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        height: 45px;
    }
    .uni-border-left {
        border-left-color: #f0f0f0;
        border-left-style: solid;
        border-left-width: 1px;
    }
    .uni-dialog-button-text {
        font-size: 16px;
        color: #333;
    }
    .uni-button-color {
        color: #007aff;
    }
    .uni-dialog-input {
        flex: 1;
        font-size: 14px;
        border: 1px #eee solid;
        height: 40px;
        padding: 0 10px;
        border-radius: 5px;
        color: #555;
    }
    .uni-popup__success {
        color: #4cd964;
    }
    .uni-popup__warn {
        color: #f0ad4e;
    }
    .uni-popup__error {
        color: #dd524d;
    }
    .uni-popup__info {
        color: #909399;
    }
</style>
uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue
New file
@@ -0,0 +1,143 @@
<template>
    <view class="uni-popup-message">
        <view class="uni-popup-message__box fixforpc-width" :class="'uni-popup__'+type">
            <slot>
                <text class="uni-popup-message-text" :class="'uni-popup__'+type+'-text'">{{message}}</text>
            </slot>
        </view>
    </view>
</template>
<script>
    import popup from '../uni-popup/popup.js'
    /**
     * PopUp 弹出层-消息提示
     * @description 弹出层-消息提示
     * @tutorial https://ext.dcloud.net.cn/plugin?id=329
     * @property {String} type = [success|warning|info|error] 主题样式
     *  @value success 成功
     *     @value warning 提示
     *     @value info 消息
     *     @value error 错误
     * @property {String} message 消息提示文字
     * @property {String} duration 显示时间,设置为 0 则不会自动关闭
     */
    export default {
        name: 'uniPopupMessage',
        mixins:[popup],
        props: {
            /**
             * 主题 success/warning/info/error      默认 success
             */
            type: {
                type: String,
                default: 'success'
            },
            /**
             * 消息文字
             */
            message: {
                type: String,
                default: ''
            },
            /**
             * 显示时间,设置为 0 则不会自动关闭
             */
            duration: {
                type: Number,
                default: 3000
            },
            maskShow:{
                type:Boolean,
                default:false
            }
        },
        data() {
            return {}
        },
        created() {
            this.popup.maskShow = this.maskShow
            this.popup.messageChild = this
        },
        methods: {
            timerClose(){
                if(this.duration === 0) return
                clearTimeout(this.timer)
                this.timer = setTimeout(()=>{
                    this.popup.close()
                },this.duration)
            }
        }
    }
</script>
<style lang="scss" >
    .uni-popup-message {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
        justify-content: center;
    }
    .uni-popup-message__box {
        background-color: #e1f3d8;
        padding: 10px 15px;
        border-color: #eee;
        border-style: solid;
        border-width: 1px;
        flex: 1;
    }
    @media screen and (min-width: 500px) {
        .fixforpc-width {
            margin-top: 20px;
            border-radius: 4px;
            flex: none;
            min-width: 380px;
            /* #ifndef APP-NVUE */
            max-width: 50%;
            /* #endif */
            /* #ifdef APP-NVUE */
            max-width: 500px;
            /* #endif */
        }
    }
    .uni-popup-message-text {
        font-size: 14px;
        padding: 0;
    }
    .uni-popup__success {
        background-color: #e1f3d8;
    }
    .uni-popup__success-text {
        color: #67C23A;
    }
    .uni-popup__warn {
        background-color: #faecd8;
    }
    .uni-popup__warn-text {
        color: #E6A23C;
    }
    .uni-popup__error {
        background-color: #fde2e2;
    }
    .uni-popup__error-text {
        color: #F56C6C;
    }
    .uni-popup__info {
        background-color: #F2F6FC;
    }
    .uni-popup__info-text {
        color: #909399;
    }
</style>
uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue
New file
@@ -0,0 +1,187 @@
<template>
    <view class="uni-popup-share">
        <view class="uni-share-title"><text class="uni-share-title-text">{{shareTitleText}}</text></view>
        <view class="uni-share-content">
            <view class="uni-share-content-box">
                <view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
                    <image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
                    <text class="uni-share-text">{{item.text}}</text>
                </view>
            </view>
        </view>
        <view class="uni-share-button-box">
            <button class="uni-share-button" @click="close">{{cancelText}}</button>
        </view>
    </view>
</template>
<script>
    import popup from '../uni-popup/popup.js'
    import {
    initVueI18n
    } from '@dcloudio/uni-i18n'
    import messages from '../uni-popup/i18n/index.js'
    const {    t    } = initVueI18n(messages)
    export default {
        name: 'UniPopupShare',
        mixins:[popup],
        emits:['select'],
        props: {
            title: {
                type: String,
                default: ''
            },
            beforeClose: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                bottomData: [{
                        text: '微信',
                        icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c2b17470-50be-11eb-b680-7980c8a877b8.png',
                        name: 'wx'
                    },
                    {
                        text: '支付宝',
                        icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/d684ae40-50be-11eb-8ff1-d5dcf8779628.png',
                        name: 'wx'
                    },
                    {
                        text: 'QQ',
                        icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/e7a79520-50be-11eb-b997-9918a5dda011.png',
                        name: 'qq'
                    },
                    {
                        text: '新浪',
                        icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/0dacdbe0-50bf-11eb-8ff1-d5dcf8779628.png',
                        name: 'sina'
                    },
                    // {
                    //     text: '百度',
                    //     icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/1ec6e920-50bf-11eb-8a36-ebb87efcf8c0.png',
                    //     name: 'copy'
                    // },
                    // {
                    //     text: '其他',
                    //     icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/2e0fdfe0-50bf-11eb-b997-9918a5dda011.png',
                    //     name: 'more'
                    // }
                ]
            }
        },
        created() {},
        computed: {
            cancelText() {
                return t("uni-popup.cancel")
            },
        shareTitleText() {
                return this.title || t("uni-popup.shareTitle")
            }
        },
        methods: {
            /**
             * 选择内容
             */
            select(item, index) {
                this.$emit('select', {
                    item,
                    index
                })
                this.close()
            },
            /**
             * 关闭窗口
             */
            close() {
                if(this.beforeClose) return
                this.popup.close()
            }
        }
    }
</script>
<style lang="scss" >
    .uni-popup-share {
        background-color: #fff;
        border-top-left-radius: 11px;
        border-top-right-radius: 11px;
    }
    .uni-share-title {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
        align-items: center;
        justify-content: center;
        height: 40px;
    }
    .uni-share-title-text {
        font-size: 14px;
        color: #666;
    }
    .uni-share-content {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
        justify-content: center;
        padding-top: 10px;
    }
    .uni-share-content-box {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
        flex-wrap: wrap;
        width: 360px;
    }
    .uni-share-content-item {
        width: 90px;
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: column;
        justify-content: center;
        padding: 10px 0;
        align-items: center;
    }
    .uni-share-content-item:active {
        background-color: #f5f5f5;
    }
    .uni-share-image {
        width: 30px;
        height: 30px;
    }
    .uni-share-text {
        margin-top: 10px;
        font-size: 14px;
        color: #3B4144;
    }
    .uni-share-button-box {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
        padding: 10px 15px;
    }
    .uni-share-button {
        flex: 1;
        border-radius: 50px;
        color: #666;
        font-size: 16px;
    }
    .uni-share-button::after {
        border-radius: 50px;
    }
</style>
uni_modules/uni-popup/components/uni-popup/i18n/en.json
New file
@@ -0,0 +1,7 @@
{
    "uni-popup.cancel": "cancel",
    "uni-popup.ok": "ok",
    "uni-popup.placeholder": "pleace enter",
    "uni-popup.title": "Hint",
    "uni-popup.shareTitle": "Share to"
}
uni_modules/uni-popup/components/uni-popup/i18n/index.js
New file
@@ -0,0 +1,8 @@
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
    en,
    'zh-Hans': zhHans,
    'zh-Hant': zhHant
}
uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json
New file
@@ -0,0 +1,7 @@
{
    "uni-popup.cancel": "取消",
    "uni-popup.ok": "确定",
    "uni-popup.placeholder": "请输入",
        "uni-popup.title": "提示",
        "uni-popup.shareTitle": "分享到"
}
uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json
New file
@@ -0,0 +1,7 @@
{
    "uni-popup.cancel": "取消",
    "uni-popup.ok": "確定",
    "uni-popup.placeholder": "請輸入",
    "uni-popup.title": "提示",
    "uni-popup.shareTitle": "分享到"
}
uni_modules/uni-popup/components/uni-popup/keypress.js
New file
@@ -0,0 +1,45 @@
// #ifdef H5
export default {
  name: 'Keypress',
  props: {
    disable: {
      type: Boolean,
      default: false
    }
  },
  mounted () {
    const keyNames = {
      esc: ['Esc', 'Escape'],
      tab: 'Tab',
      enter: 'Enter',
      space: [' ', 'Spacebar'],
      up: ['Up', 'ArrowUp'],
      left: ['Left', 'ArrowLeft'],
      right: ['Right', 'ArrowRight'],
      down: ['Down', 'ArrowDown'],
      delete: ['Backspace', 'Delete', 'Del']
    }
    const listener = ($event) => {
      if (this.disable) {
        return
      }
      const keyName = Object.keys(keyNames).find(key => {
        const keyName = $event.key
        const value = keyNames[key]
        return value === keyName || (Array.isArray(value) && value.includes(keyName))
      })
      if (keyName) {
        // 避免和其他按键事件冲突
        setTimeout(() => {
          this.$emit(keyName, {})
        }, 0)
      }
    }
    document.addEventListener('keyup', listener)
    // this.$once('hook:beforeDestroy', () => {
    //   document.removeEventListener('keyup', listener)
    // })
  },
    render: () => {}
}
// #endif
uni_modules/uni-popup/components/uni-popup/popup.js
New file
@@ -0,0 +1,26 @@
export default {
    data() {
        return {
        }
    },
    created(){
        this.popup = this.getParent()
    },
    methods:{
        /**
         * 获取父元素实例
         */
        getParent(name = 'uniPopup') {
            let parent = this.$parent;
            let parentName = parent.$options.name;
            while (parentName !== name) {
                parent = parent.$parent;
                if (!parent) return false
                parentName = parent.$options.name;
            }
            return parent;
        },
    }
}
uni_modules/uni-popup/components/uni-popup/uni-popup.vue
New file
@@ -0,0 +1,473 @@
<template>
    <view v-if="showPopup" class="uni-popup" :class="[popupstyle, isDesktop ? 'fixforpc-z-index' : '']">
        <view @touchstart="touchstart">
            <uni-transition key="1" v-if="maskShow" name="mask" mode-class="fade" :styles="maskClass"
                :duration="duration" :show="showTrans" @click="onTap" />
            <uni-transition key="2" :mode-class="ani" name="content" :styles="transClass" :duration="duration"
                :show="showTrans" @click="onTap">
                <view class="uni-popup__wrapper" :style="{ backgroundColor: bg }" :class="[popupstyle]" @click="clear">
                    <slot />
                </view>
            </uni-transition>
        </view>
        <!-- #ifdef H5 -->
        <keypress v-if="maskShow" @esc="onTap" />
        <!-- #endif -->
    </view>
</template>
<script>
    // #ifdef H5
    import keypress from './keypress.js'
    // #endif
    /**
     * PopUp 弹出层
     * @description 弹出层组件,为了解决遮罩弹层的问题
     * @tutorial https://ext.dcloud.net.cn/plugin?id=329
     * @property {String} type = [top|center|bottom|left|right|message|dialog|share] 弹出方式
     *     @value top 顶部弹出
     *     @value center 中间弹出
     *     @value bottom 底部弹出
     *     @value left        左侧弹出
     *     @value right  右侧弹出
     *     @value message 消息提示
     *     @value dialog 对话框
     *     @value share 底部分享示例
     * @property {Boolean} animation = [true|false] 是否开启动画
     * @property {Boolean} maskClick = [true|false] 蒙版点击是否关闭弹窗(废弃)
     * @property {Boolean} isMaskClick = [true|false] 蒙版点击是否关闭弹窗
     * @property {String}  backgroundColor 主窗口背景色
     * @property {String}  maskBackgroundColor 蒙版颜色
     * @property {Boolean} safeArea           是否适配底部安全区
     * @event {Function} change 打开关闭弹窗触发,e={show: false}
     * @event {Function} maskClick 点击遮罩触发
     */
    export default {
        name: 'uniPopup',
        components: {
            // #ifdef H5
            keypress
            // #endif
        },
        emits: ['change', 'maskClick'],
        props: {
            // 开启动画
            animation: {
                type: Boolean,
                default: true
            },
            // 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
            // message: 消息提示 ; dialog : 对话框
            type: {
                type: String,
                default: 'center'
            },
            // maskClick
            isMaskClick: {
                type: Boolean,
                default: null
            },
            // TODO 2 个版本后废弃属性 ,使用 isMaskClick
            maskClick: {
                type: Boolean,
                default: null
            },
            backgroundColor: {
                type: String,
                default: 'none'
            },
            safeArea: {
                type: Boolean,
                default: true
            },
            maskBackgroundColor: {
                type: String,
                default: 'rgba(0, 0, 0, 0.4)'
            },
        },
        watch: {
            /**
             * 监听type类型
             */
            type: {
                handler: function(type) {
                    if (!this.config[type]) return
                    this[this.config[type]](true)
                },
                immediate: true
            },
            isDesktop: {
                handler: function(newVal) {
                    if (!this.config[newVal]) return
                    this[this.config[this.type]](true)
                },
                immediate: true
            },
            /**
             * 监听遮罩是否可点击
             * @param {Object} val
             */
            maskClick: {
                handler: function(val) {
                    this.mkclick = val
                },
                immediate: true
            },
            isMaskClick: {
                handler: function(val) {
                    this.mkclick = val
                },
                immediate: true
            },
            // H5 下禁止底部滚动
            showPopup(show) {
                // #ifdef H5
                // fix by mehaotian 处理 h5 滚动穿透的问题
                document.getElementsByTagName('body')[0].style.overflow = show ? 'hidden' : 'visible'
                // #endif
            }
        },
        data() {
            return {
                duration: 300,
                ani: [],
                showPopup: false,
                showTrans: false,
                popupWidth: 0,
                popupHeight: 0,
                config: {
                    top: 'top',
                    bottom: 'bottom',
                    center: 'center',
                    left: 'left',
                    right: 'right',
                    message: 'top',
                    dialog: 'center',
                    share: 'bottom'
                },
                maskClass: {
                    position: 'fixed',
                    bottom: 0,
                    top: 0,
                    left: 0,
                    right: 0,
                    backgroundColor: 'rgba(0, 0, 0, 0.4)'
                },
                transClass: {
                    position: 'fixed',
                    left: 0,
                    right: 0
                },
                maskShow: true,
                mkclick: true,
                popupstyle: this.isDesktop ? 'fixforpc-top' : 'top'
            }
        },
        computed: {
            isDesktop() {
                return this.popupWidth >= 500 && this.popupHeight >= 500
            },
            bg() {
                if (this.backgroundColor === '' || this.backgroundColor === 'none') {
                    return 'transparent'
                }
                return this.backgroundColor
            }
        },
        mounted() {
            const fixSize = () => {
                const {
                    windowWidth,
                    windowHeight,
                    windowTop,
                    safeArea,
                    screenHeight,
                    safeAreaInsets
                } = uni.getSystemInfoSync()
                this.popupWidth = windowWidth
                this.popupHeight = windowHeight + (windowTop || 0)
                // TODO fix by mehaotian 是否适配底部安全区 ,目前微信ios 、和 app ios 计算有差异,需要框架修复
                if (safeArea && this.safeArea) {
                    // #ifdef MP-WEIXIN
                    this.safeAreaInsets = screenHeight - safeArea.bottom
                    // #endif
                    // #ifndef MP-WEIXIN
                    this.safeAreaInsets = safeAreaInsets.bottom
                    // #endif
                } else {
                    this.safeAreaInsets = 0
                }
            }
            fixSize()
            // #ifdef H5
            // window.addEventListener('resize', fixSize)
            // this.$once('hook:beforeDestroy', () => {
            //     window.removeEventListener('resize', fixSize)
            // })
            // #endif
        },
        // #ifndef VUE3
        // TODO vue2
        destroyed() {
            this.setH5Visible()
        },
        // #endif
        // #ifdef VUE3
        // TODO vue3
        unmounted() {
            this.setH5Visible()
        },
        // #endif
        created() {
            // this.mkclick =  this.isMaskClick || this.maskClick
            if (this.isMaskClick === null && this.maskClick === null) {
                this.mkclick = true
            } else {
                this.mkclick = this.isMaskClick !== null ? this.isMaskClick : this.maskClick
            }
            if (this.animation) {
                this.duration = 300
            } else {
                this.duration = 0
            }
            // TODO 处理 message 组件生命周期异常的问题
            this.messageChild = null
            // TODO 解决头条冒泡的问题
            this.clearPropagation = false
            this.maskClass.backgroundColor = this.maskBackgroundColor
        },
        methods: {
            setH5Visible() {
                // #ifdef H5
                // fix by mehaotian 处理 h5 滚动穿透的问题
                document.getElementsByTagName('body')[0].style.overflow = 'visible'
                // #endif
            },
            /**
             * 公用方法,不显示遮罩层
             */
            closeMask() {
                this.maskShow = false
            },
            /**
             * 公用方法,遮罩层禁止点击
             */
            disableMask() {
                this.mkclick = false
            },
            // TODO nvue 取消冒泡
            clear(e) {
                // #ifndef APP-NVUE
                e.stopPropagation()
                // #endif
                this.clearPropagation = true
            },
            open(direction) {
                // fix by mehaotian 处理快速打开关闭的情况
                if (this.showPopup) {
                    return
                }
                let innerType = ['top', 'center', 'bottom', 'left', 'right', 'message', 'dialog', 'share']
                if (!(direction && innerType.indexOf(direction) !== -1)) {
                    direction = this.type
                }
                if (!this.config[direction]) {
                    console.error('缺少类型:', direction)
                    return
                }
                this[this.config[direction]]()
                this.$emit('change', {
                    show: true,
                    type: direction
                })
            },
            close(type) {
                this.showTrans = false
                this.$emit('change', {
                    show: false,
                    type: this.type
                })
                clearTimeout(this.timer)
                // // 自定义关闭事件
                // this.customOpen && this.customClose()
                this.timer = setTimeout(() => {
                    this.showPopup = false
                }, 300)
            },
            // TODO 处理冒泡事件,头条的冒泡事件有问题 ,先这样兼容
            touchstart() {
                this.clearPropagation = false
            },
            onTap() {
                if (this.clearPropagation) {
                    // fix by mehaotian 兼容 nvue
                    this.clearPropagation = false
                    return
                }
                this.$emit('maskClick')
                if (!this.mkclick) return
                this.close()
            },
            /**
             * 顶部弹出样式处理
             */
            top(type) {
                this.popupstyle = this.isDesktop ? 'fixforpc-top' : 'top'
                this.ani = ['slide-top']
                this.transClass = {
                    position: 'fixed',
                    left: 0,
                    right: 0,
                    backgroundColor: this.bg
                }
                // TODO 兼容 type 属性 ,后续会废弃
                if (type) return
                this.showPopup = true
                this.showTrans = true
                this.$nextTick(() => {
                    if (this.messageChild && this.type === 'message') {
                        this.messageChild.timerClose()
                    }
                })
            },
            /**
             * 底部弹出样式处理
             */
            bottom(type) {
                this.popupstyle = 'bottom'
                this.ani = ['slide-bottom']
                this.transClass = {
                    position: 'fixed',
                    left: 0,
                    right: 0,
                    bottom: 0,
                    paddingBottom: this.safeAreaInsets + 'px',
                    backgroundColor: this.bg
                }
                // TODO 兼容 type 属性 ,后续会废弃
                if (type) return
                this.showPopup = true
                this.showTrans = true
            },
            /**
             * 中间弹出样式处理
             */
            center(type) {
                this.popupstyle = 'center'
                this.ani = ['zoom-out', 'fade']
                this.transClass = {
                    position: 'fixed',
                    /* #ifndef APP-NVUE */
                    display: 'flex',
                    flexDirection: 'column',
                    /* #endif */
                    bottom: 0,
                    left: 0,
                    right: 0,
                    top: 0,
                    justifyContent: 'center',
                    alignItems: 'center'
                }
                // TODO 兼容 type 属性 ,后续会废弃
                if (type) return
                this.showPopup = true
                this.showTrans = true
            },
            left(type) {
                this.popupstyle = 'left'
                this.ani = ['slide-left']
                this.transClass = {
                    position: 'fixed',
                    left: 0,
                    bottom: 0,
                    top: 0,
                    backgroundColor: this.bg,
                    /* #ifndef APP-NVUE */
                    display: 'flex',
                    flexDirection: 'column'
                    /* #endif */
                }
                // TODO 兼容 type 属性 ,后续会废弃
                if (type) return
                this.showPopup = true
                this.showTrans = true
            },
            right(type) {
                this.popupstyle = 'right'
                this.ani = ['slide-right']
                this.transClass = {
                    position: 'fixed',
                    bottom: 0,
                    right: 0,
                    top: 0,
                    backgroundColor: this.bg,
                    /* #ifndef APP-NVUE */
                    display: 'flex',
                    flexDirection: 'column'
                    /* #endif */
                }
                // TODO 兼容 type 属性 ,后续会废弃
                if (type) return
                this.showPopup = true
                this.showTrans = true
            }
        }
    }
</script>
<style lang="scss">
    .uni-popup {
        position: fixed;
        /* #ifndef APP-NVUE */
        z-index: 99;
        /* #endif */
        &.top,
        &.left,
        &.right {
            /* #ifdef H5 */
            top: var(--window-top);
            /* #endif */
            /* #ifndef H5 */
            top: 0;
            /* #endif */
        }
        .uni-popup__wrapper {
            /* #ifndef APP-NVUE */
            display: block;
            /* #endif */
            position: relative;
            /* iphonex 等安全区设置,底部安全区适配 */
            /* #ifndef APP-NVUE */
            // padding-bottom: constant(safe-area-inset-bottom);
            // padding-bottom: env(safe-area-inset-bottom);
            /* #endif */
            &.left,
            &.right {
                /* #ifdef H5 */
                padding-top: var(--window-top);
                /* #endif */
                /* #ifndef H5 */
                padding-top: 0;
                /* #endif */
                flex: 1;
            }
        }
    }
    .fixforpc-z-index {
        /* #ifndef APP-NVUE */
        z-index: 999;
        /* #endif */
    }
    .fixforpc-top {
        top: 0;
    }
</style>
uni_modules/uni-popup/package.json
New file
@@ -0,0 +1,87 @@
{
    "id": "uni-popup",
    "displayName": "uni-popup 弹出层",
    "version": "1.8.3",
    "description": " Popup 组件,提供常用的弹层",
    "keywords": [
        "uni-ui",
        "弹出层",
        "弹窗",
        "popup",
        "弹框"
    ],
    "repository": "https://github.com/dcloudio/uni-ui",
    "engines": {
        "HBuilderX": ""
    },
    "directories": {
        "example": "../../temps/example_temps"
    },
    "dcloudext": {
        "sale": {
            "regular": {
                "price": "0.00"
            },
            "sourcecode": {
                "price": "0.00"
            }
        },
        "contact": {
            "qq": ""
        },
        "declaration": {
            "ads": "无",
            "data": "无",
            "permissions": "无"
        },
        "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
        "type": "component-vue"
    },
    "uni_modules": {
        "dependencies": [
            "uni-scss",
            "uni-transition"
        ],
        "encrypt": [],
        "platforms": {
            "cloud": {
                "tcb": "y",
                "aliyun": "y"
            },
            "client": {
                "App": {
                    "app-vue": "y",
                    "app-nvue": "y"
                },
                "H5-mobile": {
                    "Safari": "y",
                    "Android Browser": "y",
                    "微信浏览器(Android)": "y",
                    "QQ浏览器(Android)": "y"
                },
                "H5-pc": {
                    "Chrome": "y",
                    "IE": "y",
                    "Edge": "y",
                    "Firefox": "y",
                    "Safari": "y"
                },
                "小程序": {
                    "微信": "y",
                    "阿里": "y",
                    "百度": "y",
                    "字节跳动": "y",
                    "QQ": "y"
                },
                "快应用": {
                    "华为": "u",
                    "联盟": "u"
                },
                "Vue": {
                    "vue2": "y",
                    "vue3": "y"
                }
            }
        }
    }
}
uni_modules/uni-popup/readme.md
New file
@@ -0,0 +1,17 @@
## Popup 弹出层
> **组件名:uni-popup**
> 代码块: `uPopup`
> 关联组件:`uni-transition`
弹出层组件,在应用中弹出一个消息提示窗口、提示框等
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-popup)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
uni_modules/uni-transition/changelog.md
New file
@@ -0,0 +1,22 @@
## 1.3.2(2023-05-04)
- 修复 NVUE 平台报错的问题
## 1.3.1(2021-11-23)
- 修复 init 方法初始化问题
## 1.3.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-transition](https://uniapp.dcloud.io/component/uniui/uni-transition)
## 1.2.1(2021-09-27)
- 修复 init 方法不生效的 Bug
## 1.2.0(2021-07-30)
- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.1(2021-05-12)
- 新增 示例地址
- 修复 示例项目缺少组件的 Bug
## 1.1.0(2021-04-22)
- 新增 通过方法自定义动画
- 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式
- 优化 动画触发逻辑,使动画更流畅
- 优化 支持单独的动画类型
- 优化 文档示例
## 1.0.2(2021-02-05)
- 调整为 uni_modules 目录规范
uni_modules/uni-transition/components/uni-transition/createAnimation.js
New file
@@ -0,0 +1,131 @@
// const defaultOption = {
//     duration: 300,
//     timingFunction: 'linear',
//     delay: 0,
//     transformOrigin: '50% 50% 0'
// }
// #ifdef APP-NVUE
const nvueAnimation = uni.requireNativePlugin('animation')
// #endif
class MPAnimation {
    constructor(options, _this) {
        this.options = options
        // 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误
        this.animation = uni.createAnimation({
            ...options
        })
        this.currentStepAnimates = {}
        this.next = 0
        this.$ = _this
    }
    _nvuePushAnimates(type, args) {
        let aniObj = this.currentStepAnimates[this.next]
        let styles = {}
        if (!aniObj) {
            styles = {
                styles: {},
                config: {}
            }
        } else {
            styles = aniObj
        }
        if (animateTypes1.includes(type)) {
            if (!styles.styles.transform) {
                styles.styles.transform = ''
            }
            let unit = ''
            if(type === 'rotate'){
                unit = 'deg'
            }
            styles.styles.transform += `${type}(${args+unit}) `
        } else {
            styles.styles[type] = `${args}`
        }
        this.currentStepAnimates[this.next] = styles
    }
    _animateRun(styles = {}, config = {}) {
        let ref = this.$.$refs['ani'].ref
        if (!ref) return
        return new Promise((resolve, reject) => {
            nvueAnimation.transition(ref, {
                styles,
                ...config
            }, res => {
                resolve()
            })
        })
    }
    _nvueNextAnimate(animates, step = 0, fn) {
        let obj = animates[step]
        if (obj) {
            let {
                styles,
                config
            } = obj
            this._animateRun(styles, config).then(() => {
                step += 1
                this._nvueNextAnimate(animates, step, fn)
            })
        } else {
            this.currentStepAnimates = {}
            typeof fn === 'function' && fn()
            this.isEnd = true
        }
    }
    step(config = {}) {
        // #ifndef APP-NVUE
        this.animation.step(config)
        // #endif
        // #ifdef APP-NVUE
        this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
        this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
        this.next++
        // #endif
        return this
    }
    run(fn) {
        // #ifndef APP-NVUE
        this.$.animationData = this.animation.export()
        this.$.timer = setTimeout(() => {
            typeof fn === 'function' && fn()
        }, this.$.durationTime)
        // #endif
        // #ifdef APP-NVUE
        this.isEnd = false
        let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
        if(!ref) return
        this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
        this.next = 0
        // #endif
    }
}
const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
    'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
    'translateZ'
]
const animateTypes2 = ['opacity', 'backgroundColor']
const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
    MPAnimation.prototype[type] = function(...args) {
        // #ifndef APP-NVUE
        this.animation[type](...args)
        // #endif
        // #ifdef APP-NVUE
        this._nvuePushAnimates(type, args)
        // #endif
        return this
    }
})
export function createAnimation(option, _this) {
    if(!_this) return
    clearTimeout(_this.timer)
    return new MPAnimation(option, _this)
}
uni_modules/uni-transition/components/uni-transition/uni-transition.vue
New file
@@ -0,0 +1,286 @@
<template>
  <!-- #ifndef APP-NVUE -->
  <view v-show="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
  <!-- #endif -->
  <!-- #ifdef APP-NVUE -->
  <view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
  <!-- #endif -->
</template>
<script>
import { createAnimation } from './createAnimation'
/**
 * Transition 过渡动画
 * @description 简单过渡动画组件
 * @tutorial https://ext.dcloud.net.cn/plugin?id=985
 * @property {Boolean} show = [false|true] 控制组件显示或隐藏
 * @property {Array|String} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
 *  @value fade 渐隐渐出过渡
 *  @value slide-top 由上至下过渡
 *  @value slide-right 由右至左过渡
 *  @value slide-bottom 由下至上过渡
 *  @value slide-left 由左至右过渡
 *  @value zoom-in 由小到大过渡
 *  @value zoom-out 由大到小过渡
 * @property {Number} duration 过渡动画持续时间
 * @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
 */
export default {
    name: 'uniTransition',
    emits:['click','change'],
    props: {
        show: {
            type: Boolean,
            default: false
        },
        modeClass: {
            type: [Array, String],
            default() {
                return 'fade'
            }
        },
        duration: {
            type: Number,
            default: 300
        },
        styles: {
            type: Object,
            default() {
                return {}
            }
        },
        customClass:{
            type: String,
            default: ''
        },
        onceRender:{
            type:Boolean,
            default:false
        },
    },
    data() {
        return {
            isShow: false,
            transform: '',
            opacity: 1,
            animationData: {},
            durationTime: 300,
            config: {}
        }
    },
    watch: {
        show: {
            handler(newVal) {
                if (newVal) {
                    this.open()
                } else {
                    // 避免上来就执行 close,导致动画错乱
                    if (this.isShow) {
                        this.close()
                    }
                }
            },
            immediate: true
        }
    },
    computed: {
        // 生成样式数据
        stylesObject() {
            let styles = {
                ...this.styles,
                'transition-duration': this.duration / 1000 + 's'
            }
            let transform = ''
            for (let i in styles) {
                let line = this.toLine(i)
                transform += line + ':' + styles[i] + ';'
            }
            return transform
        },
        // 初始化动画条件
        transformStyles() {
            return 'transform:' + this.transform + ';' + 'opacity:' + this.opacity + ';' + this.stylesObject
        }
    },
    created() {
        // 动画默认配置
        this.config = {
            duration: this.duration,
            timingFunction: 'ease',
            transformOrigin: '50% 50%',
            delay: 0
        }
        this.durationTime = this.duration
    },
    methods: {
        /**
         *  ref 触发 初始化动画
         */
        init(obj = {}) {
            if (obj.duration) {
                this.durationTime = obj.duration
            }
            this.animation = createAnimation(Object.assign(this.config, obj),this)
        },
        /**
         * 点击组件触发回调
         */
        onClick() {
            this.$emit('click', {
                detail: this.isShow
            })
        },
        /**
         * ref 触发 动画分组
         * @param {Object} obj
         */
        step(obj, config = {}) {
            if (!this.animation) return
            for (let i in obj) {
                try {
                    if(typeof obj[i] === 'object'){
                        this.animation[i](...obj[i])
                    }else{
                        this.animation[i](obj[i])
                    }
                } catch (e) {
                    console.error(`方法 ${i} 不存在`)
                }
            }
            this.animation.step(config)
            return this
        },
        /**
         *  ref 触发 执行动画
         */
        run(fn) {
            if (!this.animation) return
            this.animation.run(fn)
        },
        // 开始过度动画
        open() {
            clearTimeout(this.timer)
            this.transform = ''
            this.isShow = true
            let { opacity, transform } = this.styleInit(false)
            if (typeof opacity !== 'undefined') {
                this.opacity = opacity
            }
            this.transform = transform
            // 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常
            this.$nextTick(() => {
                // TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器
                this.timer = setTimeout(() => {
                    this.animation = createAnimation(this.config, this)
                    this.tranfromInit(false).step()
                    this.animation.run()
                    this.$emit('change', {
                        detail: this.isShow
                    })
                }, 20)
            })
        },
        // 关闭过度动画
        close(type) {
            if (!this.animation) return
            this.tranfromInit(true)
                .step()
                .run(() => {
                    this.isShow = false
                    this.animationData = null
                    this.animation = null
                    let { opacity, transform } = this.styleInit(false)
                    this.opacity = opacity || 1
                    this.transform = transform
                    this.$emit('change', {
                        detail: this.isShow
                    })
                })
        },
        // 处理动画开始前的默认样式
        styleInit(type) {
            let styles = {
                transform: ''
            }
            let buildStyle = (type, mode) => {
                if (mode === 'fade') {
                    styles.opacity = this.animationType(type)[mode]
                } else {
                    styles.transform += this.animationType(type)[mode] + ' '
                }
            }
            if (typeof this.modeClass === 'string') {
                buildStyle(type, this.modeClass)
            } else {
                this.modeClass.forEach(mode => {
                    buildStyle(type, mode)
                })
            }
            return styles
        },
        // 处理内置组合动画
        tranfromInit(type) {
            let buildTranfrom = (type, mode) => {
                let aniNum = null
                if (mode === 'fade') {
                    aniNum = type ? 0 : 1
                } else {
                    aniNum = type ? '-100%' : '0'
                    if (mode === 'zoom-in') {
                        aniNum = type ? 0.8 : 1
                    }
                    if (mode === 'zoom-out') {
                        aniNum = type ? 1.2 : 1
                    }
                    if (mode === 'slide-right') {
                        aniNum = type ? '100%' : '0'
                    }
                    if (mode === 'slide-bottom') {
                        aniNum = type ? '100%' : '0'
                    }
                }
                this.animation[this.animationMode()[mode]](aniNum)
            }
            if (typeof this.modeClass === 'string') {
                buildTranfrom(type, this.modeClass)
            } else {
                this.modeClass.forEach(mode => {
                    buildTranfrom(type, mode)
                })
            }
            return this.animation
        },
        animationType(type) {
            return {
                fade: type ? 1 : 0,
                'slide-top': `translateY(${type ? '0' : '-100%'})`,
                'slide-right': `translateX(${type ? '0' : '100%'})`,
                'slide-bottom': `translateY(${type ? '0' : '100%'})`,
                'slide-left': `translateX(${type ? '0' : '-100%'})`,
                'zoom-in': `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`,
                'zoom-out': `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`
            }
        },
        // 内置动画类型与实际动画对应字典
        animationMode() {
            return {
                fade: 'opacity',
                'slide-top': 'translateY',
                'slide-right': 'translateX',
                'slide-bottom': 'translateY',
                'slide-left': 'translateX',
                'zoom-in': 'scale',
                'zoom-out': 'scale'
            }
        },
        // 驼峰转中横线
        toLine(name) {
            return name.replace(/([A-Z])/g, '-$1').toLowerCase()
        }
    }
}
</script>
<style></style>
uni_modules/uni-transition/package.json
New file
@@ -0,0 +1,84 @@
{
  "id": "uni-transition",
  "displayName": "uni-transition 过渡动画",
  "version": "1.3.2",
  "description": "元素的简单过渡动画",
  "keywords": [
    "uni-ui",
    "uniui",
    "动画",
    "过渡",
    "过渡动画"
],
  "repository": "https://github.com/dcloudio/uni-ui",
  "engines": {
    "HBuilderX": ""
  },
  "directories": {
    "example": "../../temps/example_temps"
  },
"dcloudext": {
    "sale": {
      "regular": {
        "price": "0.00"
      },
      "sourcecode": {
        "price": "0.00"
      }
    },
    "contact": {
      "qq": ""
    },
    "declaration": {
      "ads": "无",
      "data": "无",
      "permissions": "无"
    },
    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
    "type": "component-vue"
  },
  "uni_modules": {
    "dependencies": ["uni-scss"],
    "encrypt": [],
    "platforms": {
      "cloud": {
        "tcb": "y",
        "aliyun": "y"
      },
      "client": {
        "App": {
          "app-vue": "y",
          "app-nvue": "y"
        },
        "H5-mobile": {
          "Safari": "y",
          "Android Browser": "y",
          "微信浏览器(Android)": "y",
          "QQ浏览器(Android)": "y"
        },
        "H5-pc": {
          "Chrome": "y",
          "IE": "y",
          "Edge": "y",
          "Firefox": "y",
          "Safari": "y"
        },
        "小程序": {
          "微信": "y",
          "阿里": "y",
          "百度": "y",
          "字节跳动": "y",
          "QQ": "y"
        },
        "快应用": {
          "华为": "u",
          "联盟": "u"
        },
        "Vue": {
            "vue2": "y",
            "vue3": "y"
        }
      }
    }
  }
}
uni_modules/uni-transition/readme.md
New file
@@ -0,0 +1,11 @@
## Transition 过渡动画
> **组件名:uni-transition**
> 代码块: `uTransition`
元素过渡动画
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-transition)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
uni_modules/ws-wx-privacy/changelog.md
New file
@@ -0,0 +1,22 @@
## 1.0.10(2023-09-12)
支持配置自动获取微信小程序后台的隐私协议名称
## 1.0.9(2023-09-11)
增加一些常见问题的解决办法
## 1.0.8(2023-09-11)
支持自定义主题色和背景色
## 1.0.7(2023-09-08)
优化文档示例
## 1.0.6(2023-09-07)
支持不允许不同意协议的功能,disagreeEnabled为false时,不同意按钮点击会提示disagreePromptText的内容
## 1.0.5(2023-09-05)
## README中增加关于授权的说明
## 1.0.4(2023-09-02)
强化文档中关于隐私指引调试配置的提醒
## 1.0.3(2023-09-01)
# 请注意 微信后台的用户隐私保护指引必须审核通过之后才可以调试
## 1.0.2(2023-09-01)
更新隐私保护指引调试前的配置说明
## 1.0.1(2023-08-31)
修复文案中【您点击同意并开始时用产品服务时】出现错别字的问题
## 1.0.0(2023-08-30)
微信隐私保护弹出框,支持vue2和vue3
uni_modules/ws-wx-privacy/components/ws-wx-privacy/util.js
New file
@@ -0,0 +1,51 @@
/**
 * 获取当前页面上下文
 * @returns 页面对象
 */
export function getContext() {
    // eslint-disable-next-line no-undef
    const pages = getCurrentPages()
    return pages[pages.length - 1]
}
/**
 * 获取上下文中指定节点组件
 * @param context 选择器的选择范围,可以传入自定义组件的 this 作为上下文
 * @param selector 自定义节点选择器
 */
export function getComponent(context, selector ) {
    let component = null
    // #ifdef H5
    context.$children.forEach((child) => {
        if (`#${child.$attrs.id}` === selector) {
            component = child
        } else if (child.$children && child.$children.length) {
            if (getComponent(child, selector)) {
                component = getComponent(child, selector)
            }
        }
        if (component) {
            return component
        }
    })
    // #endif
    // #ifdef MP-WEIXIN
    component = context.selectComponent && context.selectComponent(selector) && context.selectComponent(selector).$vm
    // #endif
    // #ifdef MP-ALIPAY
    const alipay = context.$children ? context.$children : context.$vm && context.$vm.$children ? context.$vm
        .$children : []
    component = alipay.find((component) => {
        return `#${component.$scope.props.id}` === selector
    })
    // #endif
    // #ifdef APP-PLUS
    const app = context.$children ? context.$children : context.$vm && context.$vm.$children ? context.$vm.$children :
    []
    component = app.find((component) => {
        return `#${component.$attrs.id}` === selector
    })
    // #endif
    return component
}
uni_modules/ws-wx-privacy/components/ws-wx-privacy/ws-wx-privacy.vue
New file
@@ -0,0 +1,287 @@
<template>
    <uni-popup id="privacy" type="center" ref="privacyPopup" :maskClick="false">
        <view class="ws-privacy-popup" :style="rootStyle">
            <view class="ws-privacy-popup__header">
                <!--标题-->
                <view class="ws-picker__title">{{ title }}</view>
            </view>
            <view class="ws-privacy-popup__container">
                <text>{{ desc }}</text>
                <text class="ws-privacy-popup__container-protocol" :style="protocolStyle"
                    @click="openPrivacyContract">{{ privacyContractName||protocol }}</text>
                <text>{{ subDesc }}</text>
            </view>
            <view class="ws-privacy-popup__footer">
                <button class="is-agree" :style="agreeStyle" id="agree-btn" open-type="agreePrivacyAuthorization"
                    @agreeprivacyauthorization="handleAgree">
                    {{agreeText}}
                </button>
                <button class="is-disagree" id="disagree-btn" @click="handleDisagree">
                    {{disagreeText}}
                </button>
            </view>
        </view>
    </uni-popup>
</template>
<script>
    import {
        getContext,
        getComponent
    } from './util'
    const privacyResolves = new Set() // onNeedPrivacyAuthorization的reslove
    let privacyHandler = null
    // 注册监听
    if (uni.onNeedPrivacyAuthorization) {
        uni.onNeedPrivacyAuthorization((resolve) => {
            if (typeof privacyHandler === 'function') {
                privacyHandler(resolve)
            }
        })
    }
    export default {
        name: 'wsWxPrivacy',
        emits: ['disagree', 'agree'],
        props: {
            // 标题
            title: {
                type: String,
                default: '用户隐私保护提示'
            },
            // 描述
            desc: {
                type: String,
                default: '感谢您使用本应用,您使用本应用的服务之前请仔细阅读并同意'
            },
            // 自定义隐私保护指引名称
            protocol: {
                type: String,
                default: '《用户隐私保护指引》'
            },
            // 是否自动获取隐私保护指引名称(开启后调用getPrivacySetting获取名称)
            enableAutoProtocol: {
                type: Boolean,
                default: false, // 默认为使用自定义隐私指引名称
            },
            // 子描述
            subDesc: {
                type: String,
                default: '。当您点击同意并开始使用产品服务时,即表示你已理解并同意该条款内容,该条款将对您产生法律约束力。如您拒绝,将无法使用相应服务。'
            },
            /**
             * 控制是否可以点击不同意按钮并显示提示。
             * 如果设置为 true,用户可以点击不同意按钮执行后续逻辑。
             * 如果设置为 false,点击不同意按钮会显示提示信息,但不会执行后续逻辑。
             * 默认为 true
             */
            disagreeEnabled: {
                type: Boolean,
                default: true, // 默认为可以点击
            },
            /**
             * 配置不同意按钮的提示消息内容。
             */
            disagreePromptText: {
                type: String,
                default: '请先仔细阅读并同意隐私协议', // 默认提示消息
            },
            // 拒绝按钮文字
            disagreeText: {
                type: String,
                default: '不同意'
            },
            // 同意按钮文字
            agreeText: {
                type: String,
                default: '同意并继续'
            },
            // 自定义背景颜色
            bgColor: {
                type: String,
                default: ''
            },
            // 自定义主题颜色(控制同意按钮和隐私协议名称的颜色)
            themeColor: {
                type: String,
                default: ''
            }
        },
        data() {
            return {
                privacyContractName: '',
            }
        },
        computed: {
            rootStyle() {
                if (this.bgColor) {
                    return `background:${this.bgColor}`
                } else {
                    return ''
                }
            },
            protocolStyle() {
                if (this.themeColor) {
                    return `color:${this.themeColor}`
                } else {
                    return ''
                }
            },
            agreeStyle() {
                if (this.themeColor) {
                    return `background:${this.themeColor}`
                } else {
                    return ''
                }
            }
        },
        created() {
            privacyHandler = (resolve) => {
                const context = getContext()
                const privacyPopup = getComponent(context, '#privacy-popup')
                if (privacyPopup) {
                    const privacy = getComponent(privacyPopup, '#privacy')
                    if (privacy && privacy.open) {
                        privacy.open()
                    }
                }
                privacyResolves.add(resolve)
            }
            if (this.enableAutoProtocol && uni.getPrivacySetting) {
                uni.getPrivacySetting({
                    success: res => {
                        if (res.privacyContractName) {
                            this.privacyContractName = res.privacyContractName
                        }
                    },
                    fail: () => {},
                    complete: () => {}
                })
            }
        },
        methods: {
            /**
             * 打开隐私协议
             */
            openPrivacyContract() {
                wx.openPrivacyContract({
                    success: (res) => {
                        console.log('openPrivacyContract success')
                    },
                    fail: (res) => {
                        console.error('openPrivacyContract fail', res)
                    }
                })
            },
            /**
             * 拒绝隐私协议
             */
            handleDisagree() {
                if (this.disagreeEnabled) {
                    this.$refs.privacyPopup.close()
                    privacyResolves.forEach((resolve) => {
                        resolve({
                            event: 'disagree'
                        })
                    })
                    privacyResolves.clear()
                    this.$emit('disagree')
                } else {
                    uni.showToast({
                        icon: 'none',
                        title: this.disagreePromptText
                    })
                }
            },
            /**
             * 同意隐私协议
             */
            handleAgree() {
                this.$refs.privacyPopup.close()
                privacyResolves.forEach((resolve) => {
                    resolve({
                        event: 'agree',
                        buttonId: 'agree-btn'
                    })
                })
                privacyResolves.clear()
                this.$emit('agree')
            }
        }
    }
</script>
<style lang="scss" scoped>
    .ws-privacy-popup {
        padding: 48rpx;
        box-sizing: border-box;
        overflow: hidden;
        width: 560rpx;
        background: linear-gradient(180deg, #e5edff 0%, #ffffff 100%);
        border-radius: 24rpx;
        &__header {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 100%;
            height: 52rpx;
            font-size: 36rpx;
            font-family: PingFangSC-Medium, PingFang SC;
            font-weight: 550;
            color: #1a1a1a;
            line-height: 52rpx;
            margin-bottom: 48rpx;
        }
        &__container {
            width: 100%;
            box-sizing: border-box;
            font-size: 28rpx;
            font-family: PingFangSC-Regular, PingFang SC;
            font-weight: 400;
            color: #333333;
            line-height: 48rpx;
            margin-bottom: 48rpx;
            &-protocol {
                font-weight: 550;
                color: #4D80F0;
            }
        }
        &__footer {
            display: flex;
            flex-direction: column;
            .is-disagree,
            .is-agree {
                width: 100%;
                height: 88rpx;
                background: #ffffff;
                border-radius: 44rpx;
                font-size: 32rpx;
                font-family: PingFangSC-Regular, PingFang SC;
                font-weight: 400;
                color: #666666;
            }
            .is-agree {
                background: #4D80F0;
                color: #ffffff;
                margin-bottom: 18rpx;
            }
            button {
                border: none;
                outline: none;
                &::after {
                    border: none;
                }
            }
        }
    }
</style>
uni_modules/ws-wx-privacy/package.json
New file
@@ -0,0 +1,85 @@
{
  "id": "ws-wx-privacy",
  "displayName": "ws-wx-privacy 微信隐私保护弹出框 隐私协议弹出框",
  "version": "1.0.10",
  "description": "微信隐私保护弹出框 隐私协议弹出框,支持vue2和vue3,支持自定义文字和颜色 ws-wx-privacy,有问题评论区沟通,恶意差评走开。",
  "keywords": [
    "微信小程序",
    "隐私保护",
    "隐私保护指引",
    "隐私协议",
    "隐私"
],
  "repository": "",
  "engines": {
    "HBuilderX": "^3.8.6"
  },
  "dcloudext": {
    "type": "component-vue",
    "sale": {
      "regular": {
        "price": "0.00"
      },
      "sourcecode": {
        "price": "0.00"
      }
    },
    "contact": {
      "qq": ""
    },
    "declaration": {
      "ads": "无",
      "data": "插件不采集任何数据",
      "permissions": "无"
    },
    "npmurl": ""
  },
  "uni_modules": {
    "dependencies": ["uni-popup"],
    "encrypt": [],
    "platforms": {
      "cloud": {
        "tcb": "y",
        "aliyun": "y"
      },
      "client": {
        "Vue": {
          "vue2": "y",
          "vue3": "y"
        },
        "App": {
          "app-vue": "n",
          "app-nvue": "n"
        },
        "H5-mobile": {
          "Safari": "n",
          "Android Browser": "n",
          "微信浏览器(Android)": "n",
          "QQ浏览器(Android)": "n"
        },
        "H5-pc": {
          "Chrome": "n",
          "IE": "n",
          "Edge": "n",
          "Firefox": "n",
          "Safari": "n"
        },
        "小程序": {
          "微信": "y",
          "阿里": "n",
          "百度": "n",
          "字节跳动": "n",
          "QQ": "n",
          "钉钉": "n",
          "快手": "n",
          "飞书": "n",
          "京东": "n"
        },
        "快应用": {
          "华为": "n",
          "联盟": "n"
        }
      }
    }
  }
}
uni_modules/ws-wx-privacy/readme.md
New file
@@ -0,0 +1,122 @@
# ws-wx-privacy  隐私保护弹窗组件
本组件基于微信小程序官方政策开发,[关于小程序隐私保护指引设置的公告](https://developers.weixin.qq.com/community/develop/doc/00042e3ef54940ce8520e38db61801?blockType=1&page=1#comment-list)
`wsWxPrivacy` 组件用于显示隐私保护提示的弹窗,用户可以选择同意或不同意隐私协议。
# 请注意 微信后台的用户隐私保护指引必须审核通过之后才可以调试
### 注意事项
1. 请使用HbuilderX导入,因为本组件依赖`uni-popup`直接下载会丢失依赖。
2. 部分隐私接口需要用`wx.requirePrivacyAuthorize`接口包装,请仔细阅读[微信小程序隐私协议开发指南](https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/PrivacyAuthorize.html)
3. popup可以自行替换为自己使用的组件,以减小小程序包体积,不过需要注意使用`util.js`中的方法获取组件并打开,使用ref可能会因为this指向的问题导致无法打开弹出框
4. 导入demo项目请选择vue3版本,导入组件不限。
### 隐私指引调试配置(必须配置完成才可以顺利调试)
执行完以下三个步骤之后才可以顺利调试隐私指引内容,如有问题请先自查下边三个步骤是否都完成
#### 1.更新用户隐私保护指引(必需)
小程序管理员或开发者可以根据具体小程序涉及到的[隐私相关接口](https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/miniprogram-intro.html)来更新微信小程序后台的`用户隐私保护指引`,更新并审核通过后就可以进行相关的开发调试工作。
`需要注意的是,仅有在指引中声明所处理的用户信息,才可以调用平台提供的对应接口或组件。若未声明,对应接口或组件将直接禁用`
`微信后台的用户隐私保护指引必须审核通过之后才可以调试,必须审核通过!审核通过!审核通过!`
#### 2.配置调试字段__usePrivacyCheck__ (必需)
参考 [微信小程序隐私协议开发指南](https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/PrivacyAuthorize.html)中的介绍
目前 `getPrivacySetting`、`onNeedPrivacyAuthorization`、`requirePrivacyAuthorize` 等接口目前可以正常接入调试。调试说明:
- 在 2023 年 9 月 15 号之前,在 app.json 中配置 `"__usePrivacyCheck__": true` 后,会启用隐私相关功能,如果不配置或者配置为 false 则不会启用。
- 在 2023 年 9 月 15 号之后,不论 app.json 中是否有配置 **usePrivacyCheck**,隐私相关功能都会启用。
所以在基于`uni-app`开发时,我们在 2023 年 9 月 15 号之前进行相关开发调试则需要在`manifest.json`文件`mp-weixin`中添加`"__usePrivacyCheck__": true`
#### 3.配置微信开发工具基础库(必需)
将调试基础库改为3.0.0以上。具体路径为:
微信开发者工具->详情->本地设置->调试基础库
#### 4.如果三个步骤都做完了,还是无法调起弹出框
可以使用getPrivacySetting接口查询一下是否已经授权,已经授权就不会调起弹出框了,这时候需要将缓存清除。
### Props
| 属性                | 类型        | 默认值                            | 描述                                                                                                                                                                    |
|------------        |--------    |----------------------------------    |------------------------------------------------------------------------------------------                                                                                |
| title                | String    | 用户隐私保护提示                    | 弹窗标题。                                                                                                                                                            |
| desc                | String    | 感谢您使用本应用,...                | 弹窗描述。                                                                                                                                                            |
| protocol            | String    | 用户隐私保护指引                    | 隐私保护指引的名称。                                                                                                                                                    |
| subDesc            | String    | 。当您点击同意并开始时...            | 子描述,进一步解释同意隐私协议的含义。                                                                                                                                |
| disagreeEnabled    | Boolean    | true                                | 是否允许拒绝。控制是否可以点击不同意按钮并执行后续逻辑。如果设置为 true,用户可以点击不同意按钮执行后续逻辑。如果设置为 false,点击不同意按钮会显示提示信息,但不会执行后续逻辑。    |
| disagreePromptText| String    | 请先仔细阅读并同意隐私协议        | 不同意按钮的提示消息内容。                                                                                                                                        |
| bgColor           | String   |  -                                | 自定义背景颜色。                                                                                                                                   |
| themeColor        | String   |  -                               | 自定义主题颜色(控制同意按钮和隐私协议名称的颜色)。                                                                                              |
### Events
| 事件      | 参数                                   | 描述                                                                                   |
|-----------|----------------------------------------|----------------------------------------------------------------------------------------|
| disagree  | 无参数                                 | 用户选择不同意隐私协议时触发的事件。                                                       |
| agree     | 无参数                                 | 用户选择同意隐私协议时触发的事件。                                                       |
### 使用示例
请确保你已经阅读或了解过[uni-modules 规范](https://uniapp.dcloud.net.cn/plugin/uni_modules.html#uni-modules)
使用hbuildX导入组件后可以直接使用,无需import。
```vue
<template>
  <view>
  <!-- #ifdef MP-WEIXIN -->
  <ws-wx-privacy id="privacy-popup"></ws-wx-privacy>
  <!-- #endif -->
  </view>
</template>
<script>
export default {
  components: {},
  methods: {
    handleDisagree() {
      // 处理用户不同意隐私协议的逻辑
    },
    handleAgree() {
      // 处理用户同意隐私协议的逻辑
    }
  }
}
</script>
```
请注意,上述示例中的组件路径和事件处理逻辑可能需要根据实际情况进行调整。其中`id="privacy-popup"`必填,目的是为了解决多个连续页面同时引入,造成的this指向错误的问题。
## 授权协议
```
1. 企业或个人可以免费商用。
2. 企业或个人不得复制、改造传播并分发本组件。
3. 如果你想分享本组件及教程,请保留本组件的下载地址以及作者名称。
```
## 常见问题
### 1.弹出框弹不出来?
#### 一、请先自检"隐私指引调试配置(必须配置完成才可以顺利调试)"章节的配置是否完成(隐私协议一定要包含调用的API且隐私协议要审核通过)
#### 二、然后看看微信开发者工具是否最新
#### 三、其次使用getPrivacySetting接口看一下是否已经授权过了
### 2.示例项目跑不起来?
#### 请先看看是否选择了vue3下载,如果不是重新选择vue3下载。
### 3.组件是否支持vue2
#### 支持
### 4.chooseImage同意了但是没有弹出选图片的界面?
#### 也是参考常见问题1,隐私协议是否审核通过且包含选取图片的API
### 5.如何知道隐私协议里面该配哪些权限
#### 在[隐私相关接口](https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/miniprogram-intro.html)里面找你用到的API,例如uni.chooseImage对应“收集你选中的照片或视频信息    ”
## Vue3高颜值组件库推荐
这里推荐一下[wot-design-uni](https://ext.dcloud.net.cn/plugin?id=13889),支持暗黑模式自定义主题的高颜值组件库,提供50+组件。
utils/websoket.js
New file
@@ -0,0 +1,91 @@
class websocketUtil {
    constructor(url, time) {
        this.is_open_socket = false //避免重复连接
        this.url = url //地址
        this.data = null
        //心跳检测
        this.timeout = time //多少秒执行检测
        this.heartbeatInterval = null //检测服务器端是否还活着
        this.reconnectTimeOut = null //重连之后多久再次重连
        try {
            return this.connectSocketInit()
        } catch (e) {
            console.log('catch');
            this.is_open_socket = false
            this.reconnect();
        }
    }
    // 进入这个页面的时候创建websocket连接【整个页面随时使用】
    connectSocketInit() {
        this.socketTask = uni.connectSocket({
            url: this.url,
            success: () => {
                console.log("正准备建立websocket中...");
                // 返回实例
                return this.socketTask
            },
        });
        this.socketTask.onOpen((res) => {
            console.log("WebSocket连接正常!");
            clearTimeout(this.reconnectTimeOut)
            clearTimeout(this.heartbeatInterval)
            this.is_open_socket = true;
            this.start();
            // 注:只有连接正常打开中 ,才能正常收到消息
            this.socketTask.onMessage((res) => {
                console.log(res.data)
            });
        })
        // 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接
        // uni.onSocketError((res) => {
        //     console.log('WebSocket连接打开失败,请检查!');
        //     this.is_open_socket = false;
        //     this.reconnect();
        // });
        // 这里仅是事件监听【如果socket关闭了会执行】
        this.socketTask.onClose(() => {
            console.log("已经被关闭了")
            this.is_open_socket = false;
            this.reconnect();
        })
    }
    //发送消息
    send(value) {
        // 注:只有连接正常打开中 ,才能正常成功发送消息
        this.socketTask.send({
            data: value,
            async success() {
                console.log("消息发送成功");
            },
        });
    }
    //开启心跳检测
    start() {
        this.heartbeatInterval = setTimeout(() => {
            this.data = {
                value: "传输内容",
                method: "方法名称"
            }
            console.log(this.data)
            this.send(JSON.stringify(this.data));
        }, this.timeout)
    }
    //重新连接
    reconnect() {
        //停止发送心跳
        clearInterval(this.heartbeatInterval)
        //如果不是人为关闭的话,进行重连
        if (!this.is_open_socket) {
            this.reconnectTimeOut = setTimeout(() => {
                this.connectSocketInit();
            }, 3000)
        }
    }
    //外部获取消息
    getMessage(callback) {
        this.socketTask.onMessage((res) => {
            return callback(res)
        })
    }
}
module.exports = websocketUtil