Merge branch 'app' into 'develop'
App See merge request StarlockTeam/wx-starlock!40
This commit is contained in:
commit
1cb16ae299
7
App.vue
7
App.vue
@ -36,12 +36,15 @@
|
||||
...mapState(useBluetoothStore, ['bluetoothStatus'])
|
||||
},
|
||||
async onLaunch() {
|
||||
// #ifdef MP-WEIXIN
|
||||
// 检查强制升级
|
||||
this.updateMiniProgram()
|
||||
// 监听蓝牙开关状态
|
||||
this.onBluetoothState()
|
||||
// 设置voip配置
|
||||
this.setVoipConfig()
|
||||
// #endif
|
||||
|
||||
// 监听蓝牙开关状态
|
||||
this.onBluetoothState()
|
||||
// 检查蓝牙权限
|
||||
const checkResult = await this.checkSetting()
|
||||
console.log(checkResult)
|
||||
|
||||
20
README.md
20
README.md
@ -1,17 +1,23 @@
|
||||
# 项目说明
|
||||
|
||||
## 功能
|
||||
#### 功能与星锁app相同,在其基础上简化
|
||||
|
||||
### 功能与星锁app相同,在其基础上简化
|
||||
|
||||
## 使用工具
|
||||
#### HBuilderX + 微信开发者工具(推荐使用IntelliJ工具编写,HBuilderX代码提示等功能做的较差)
|
||||
|
||||
### HBuilderX + 微信开发者工具(推荐使用IntelliJ工具编写,HBuilderX代码提示等功能做的较差)
|
||||
|
||||
## 技术栈 + 运行方式
|
||||
#### [uni-app](https://uniapp.dcloud.net.cn/)创建的vue3项目,目前并未使用uni-app x和uniCloud,主要使用vue3 + pinia + uview-plus
|
||||
#### 在HBuilderX中点击 文件 -> 导入 -> 从本地目录导入,选择项目目录即可导入项目
|
||||
#### 运行只需执行`npm i` 安装依赖(node版本 v20.16),然后在HBuilderX中点击运行 -> 运行到微信开发者工具即可(运行前勾选运行时压缩代码)
|
||||
|
||||
### [uni-app](https://uniapp.dcloud.net.cn/)创建的vue3项目,目前并未使用uni-app x和uniCloud,主要使用vue3 + pinia + uview-plus
|
||||
|
||||
### 在HBuilderX中点击 文件 -> 导入 -> 从本地目录导入,选择项目目录即可导入项目
|
||||
|
||||
### 运行只需执行`npm i` 安装依赖(node版本 v20.16),然后在HBuilderX中点击运行 -> 运行到微信开发者工具即可(运行前勾选运行时压缩代码)
|
||||
|
||||
## 目录
|
||||
|
||||
1. api 项目接口
|
||||
2. config 项目不同环境配置
|
||||
3. pages 项目页面
|
||||
@ -20,7 +26,9 @@
|
||||
6. utils 项目公共方法
|
||||
|
||||
## 公共方法
|
||||
#### 示例在index页面中,后续添加公共方法会在文档中说明
|
||||
|
||||
### 示例在index页面中,后续添加公共方法会在文档中说明
|
||||
|
||||
1. utils/request 请求方法
|
||||
2. pinia 全局状态管理
|
||||
3. [uview-plus](https://uiadmin.net/uview-plus/components/intro.html) Uni-app常用UI组件库,且提供很多常用api
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
v-if="tip"
|
||||
name="question-circle-fill"
|
||||
color="#555555"
|
||||
size="38"
|
||||
size="38rpx"
|
||||
@click="tipDialog"
|
||||
></up-icon>
|
||||
</view>
|
||||
|
||||
@ -1,45 +1,42 @@
|
||||
{
|
||||
"name": "wx-starlock",
|
||||
"appid": "__UNI__933D519",
|
||||
"description": "",
|
||||
"versionName": "1.2.0",
|
||||
"versionCode": "35",
|
||||
"mp-weixin": {
|
||||
"appid": "wx9829a39e65550757",
|
||||
"setting": {
|
||||
"urlCheck": true,
|
||||
"minified": true
|
||||
},
|
||||
"permission": {
|
||||
"scope.bluetooth": {
|
||||
"desc": "蓝牙将用于控制和管理您的智能门锁"
|
||||
},
|
||||
"scope.userLocation": {
|
||||
"desc": "获取您的位置信息将用于智能门锁的位置服务"
|
||||
}
|
||||
},
|
||||
"requiredPrivateInfos": ["getLocation"],
|
||||
"usingComponents": true,
|
||||
"lazyCodeLoading": "requiredComponents",
|
||||
"optimization": {
|
||||
"subPackages": true
|
||||
},
|
||||
"plugins": {
|
||||
"xp2p": {
|
||||
"version": "latest",
|
||||
"provider": "wx1319af22356934bf",
|
||||
"export": "exportForXp2pPlugin.js"
|
||||
},
|
||||
"wmpf-voip": {
|
||||
"version": "latest",
|
||||
"provider": "wxf830863afde621eb",
|
||||
"genericsImplementation": {
|
||||
"call-page-plugin": {
|
||||
"custombox": "pages/main/customBox"
|
||||
}
|
||||
"name" : "wx-starlock",
|
||||
"appid" : "__UNI__933D519",
|
||||
"description" : "",
|
||||
"versionName" : "1.3.0",
|
||||
"versionCode" : "37",
|
||||
"mp-weixin" : {
|
||||
"appid" : "wx9829a39e65550757",
|
||||
"setting" : {
|
||||
"urlCheck" : true,
|
||||
"minified" : true
|
||||
},
|
||||
"permission" : {
|
||||
"scope.bluetooth" : {
|
||||
"desc" : "蓝牙将用于控制和管理您的智能门锁"
|
||||
}
|
||||
},
|
||||
"requiredPrivateInfos" : [ "getLocation" ],
|
||||
"usingComponents" : true,
|
||||
"lazyCodeLoading" : "requiredComponents",
|
||||
"optimization" : {
|
||||
"subPackages" : true
|
||||
},
|
||||
"plugins" : {
|
||||
"xp2p" : {
|
||||
"version" : "latest",
|
||||
"provider" : "wx1319af22356934bf",
|
||||
"export" : "exportForXp2pPlugin.js"
|
||||
},
|
||||
"wmpf-voip" : {
|
||||
"version" : "latest",
|
||||
"provider" : "wxf830863afde621eb",
|
||||
"genericsImplementation" : {
|
||||
"call-page-plugin" : {
|
||||
"custombox" : "pages/main/customBox"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vueVersion": "3"
|
||||
},
|
||||
"vueVersion" : "3"
|
||||
}
|
||||
|
||||
57
package-lock.json
generated
57
package-lock.json
generated
@ -12,6 +12,10 @@
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.7.1",
|
||||
"@commitlint/config-conventional": "^19.7.1",
|
||||
"@iconify-json/material-symbols": "^1.2.22",
|
||||
"@iconify-json/solar": "^1.2.2",
|
||||
"@iconify/utils": "^2.3.0",
|
||||
"@unocss/preset-icons": "^66.1.2",
|
||||
"commitizen": "^4.3.1",
|
||||
"crc": "^4.3.2",
|
||||
"cz-git": "^1.11.0",
|
||||
@ -1049,6 +1053,26 @@
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@iconify-json/material-symbols": {
|
||||
"version": "1.2.22",
|
||||
"resolved": "https://registry.npmjs.org/@iconify-json/material-symbols/-/material-symbols-1.2.22.tgz",
|
||||
"integrity": "sha512-raleOIRt8iPtwAkDzmw/c5zb06nIaicsYs5bZ3yfRjBxuYT/UYNa2ZFQQMl3uuTTiZuUXwFa1M8PJW3CFRAN0w==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@iconify/types": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@iconify-json/solar": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@iconify-json/solar/-/solar-1.2.2.tgz",
|
||||
"integrity": "sha512-lcTb6DWL4HZObiY1W3fHfuxxuQHUc6CFHFeywKEx7Ry0k+dU6POZCMC7oVLr0F8vuf+KgaQ3oOoGO/yFzOwrNg==",
|
||||
"dev": true,
|
||||
"license": "CC-BY-4.0",
|
||||
"dependencies": {
|
||||
"@iconify/types": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@iconify/types": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
|
||||
@ -1771,20 +1795,30 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@unocss/preset-icons": {
|
||||
"version": "65.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@unocss/preset-icons/-/preset-icons-65.5.0.tgz",
|
||||
"integrity": "sha512-lSwMNtj4nufpQDBFoioAM9S6hP8028lA9fLFM3Vw+KmI10/3TaZyOaCXJVH5UdsfNWexGGo/Qo+K1YFWfXLZ8A==",
|
||||
"version": "66.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@unocss/preset-icons/-/preset-icons-66.1.2.tgz",
|
||||
"integrity": "sha512-14390jFBJ2anuKvjX9TeRCm7adNjR/mey0bh0+S/k/5W3VugIY2y0E+OH3m+sx5d/5ZUYbYkUGsmtuKbVNwwxQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@iconify/utils": "^2.3.0",
|
||||
"@unocss/core": "65.5.0",
|
||||
"@unocss/core": "66.1.2",
|
||||
"ofetch": "^1.4.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@unocss/preset-icons/node_modules/@unocss/core": {
|
||||
"version": "66.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@unocss/core/-/core-66.1.2.tgz",
|
||||
"integrity": "sha512-mN9h1hHEuhDcdbI4z74o7UnxlBZYVsJpYcdC1YLWBKROcLYTkuyZ7hgBzpo1FBNox2Bt3JnrSinVDmc44Bxjow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@unocss/preset-mini": {
|
||||
"version": "65.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@unocss/preset-mini/-/preset-mini-65.5.0.tgz",
|
||||
@ -9402,6 +9436,21 @@
|
||||
"unplugin-transform-class": "^0.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/unocss/node_modules/@unocss/preset-icons": {
|
||||
"version": "65.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@unocss/preset-icons/-/preset-icons-65.5.0.tgz",
|
||||
"integrity": "sha512-lSwMNtj4nufpQDBFoioAM9S6hP8028lA9fLFM3Vw+KmI10/3TaZyOaCXJVH5UdsfNWexGGo/Qo+K1YFWfXLZ8A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@iconify/utils": "^2.3.0",
|
||||
"@unocss/core": "65.5.0",
|
||||
"ofetch": "^1.4.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz",
|
||||
|
||||
@ -7,6 +7,10 @@
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.7.1",
|
||||
"@commitlint/config-conventional": "^19.7.1",
|
||||
"@iconify-json/material-symbols": "^1.2.22",
|
||||
"@iconify-json/solar": "^1.2.2",
|
||||
"@iconify/utils": "^2.3.0",
|
||||
"@unocss/preset-icons": "^66.1.2",
|
||||
"commitizen": "^4.3.1",
|
||||
"crc": "^4.3.2",
|
||||
"cz-git": "^1.11.0",
|
||||
|
||||
37
pages.json
37
pages.json
@ -32,22 +32,11 @@
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "videoDetail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "视频播放"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "videoLog",
|
||||
"style": {
|
||||
"navigationBarTitleText": "云存"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "videoEdit",
|
||||
"style": {
|
||||
"navigationBarTitleText": "视频编辑"
|
||||
"navigationBarTitleText": "门锁记录",
|
||||
"disableScroll": true
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -82,13 +71,6 @@
|
||||
"navigationBarTitleText": "附近设备"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "selectAddress",
|
||||
"style": {
|
||||
"navigationBarTitleText": "锁地址",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "distributionNetwork",
|
||||
"style": {
|
||||
@ -611,13 +593,22 @@
|
||||
],
|
||||
"preloadRule": {
|
||||
"pages/main/home": {
|
||||
"packages": ["pages/others", "pages/addDevice", "pages/p2p"]
|
||||
"packages": [
|
||||
"pages/others",
|
||||
"pages/addDevice",
|
||||
"pages/p2p"
|
||||
]
|
||||
},
|
||||
"pages/main/lockDetail": {
|
||||
"packages": ["pages/feature", "pages/setting"]
|
||||
"packages": [
|
||||
"pages/feature",
|
||||
"pages/setting"
|
||||
]
|
||||
},
|
||||
"pages/main/mine": {
|
||||
"packages": ["pages/user"]
|
||||
"packages": [
|
||||
"pages/user"
|
||||
]
|
||||
}
|
||||
},
|
||||
"globalStyle": {
|
||||
|
||||
@ -131,7 +131,7 @@
|
||||
if (data.status === 0) {
|
||||
$basic.routeJump({
|
||||
type: 'redirectTo',
|
||||
name: 'selectAddress'
|
||||
name: 'bindLock'
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.showToast({
|
||||
|
||||
@ -143,7 +143,7 @@
|
||||
name:
|
||||
this.currentLockInfo.lockConfig.model === model.TENCENT_YUN_LOCK
|
||||
? 'distributionNetwork'
|
||||
: 'selectAddress'
|
||||
: 'bindLock'
|
||||
})
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
|
||||
@ -1,283 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="title">地理位置</view>
|
||||
<view v-if="show">
|
||||
<map
|
||||
class="map"
|
||||
:longitude="longitude"
|
||||
:latitude="latitude"
|
||||
:scale="16"
|
||||
:markers="markers"
|
||||
:enable-zoom="true"
|
||||
:enable-scroll="true"
|
||||
></map>
|
||||
</view>
|
||||
<view v-else class="map"></view>
|
||||
<view class="explain">检查以确保以下地址是正确的</view>
|
||||
<view
|
||||
class="view-address"
|
||||
:style="{ height: calculateStringTotalWidth(address) > 44 ? '120rpx' : '80rpx' }"
|
||||
>
|
||||
<view class="address">{{ address }}</view>
|
||||
</view>
|
||||
<view class="bottom">
|
||||
<view class="skip" @click="skipAddress">跳过</view>
|
||||
<view class="confirm" @click="toBindLock">下一步</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapActions } from 'pinia'
|
||||
import { useBasicStore } from '@/stores/basic'
|
||||
import { getGeocodeAddress } from '@/api/geocode'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
latitude: null,
|
||||
longitude: null,
|
||||
show: false,
|
||||
markers: [],
|
||||
address: '',
|
||||
first: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useBluetoothStore, ['currentLockInfo'])
|
||||
},
|
||||
onLoad() {
|
||||
this.getLocation()
|
||||
},
|
||||
onShow() {
|
||||
if (this.first) {
|
||||
this.first = false
|
||||
} else if (!this.show) {
|
||||
this.getLocation()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useBasicStore, ['routeJump', 'calculateStringTotalWidth']),
|
||||
...mapActions(useBluetoothStore, ['updateCurrentLockInfo']),
|
||||
toBindLock() {
|
||||
const that = this
|
||||
if (this.address === '') {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '暂未获取到地理位置信息,请重试',
|
||||
confirmText: '重试',
|
||||
success: res => {
|
||||
if (res.confirm) {
|
||||
that.getLocation()
|
||||
}
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
this.routeJump({
|
||||
type: 'redirectTo',
|
||||
name: 'bindLock'
|
||||
})
|
||||
},
|
||||
skipAddress() {
|
||||
const that = this
|
||||
if (this.address !== '') {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '已获取当前地理位置,确定跳过吗',
|
||||
confirmText: '跳过',
|
||||
cancelText: '取消',
|
||||
success: res => {
|
||||
if (res.confirm) {
|
||||
const lockInfo = that.currentLockInfo
|
||||
delete lockInfo.position
|
||||
that.updateCurrentLockInfo(lockInfo)
|
||||
this.routeJump({
|
||||
type: 'redirectTo',
|
||||
name: 'bindLock'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
this.routeJump({
|
||||
type: 'redirectTo',
|
||||
name: 'bindLock'
|
||||
})
|
||||
},
|
||||
async getLocation() {
|
||||
const that = this
|
||||
uni.getLocation({
|
||||
isHighAccuracy: true,
|
||||
type: 'gcj02',
|
||||
async success(res) {
|
||||
that.latitude = res.latitude
|
||||
that.longitude = res.longitude
|
||||
that.markers = [
|
||||
{
|
||||
id: 1,
|
||||
latitude: res.latitude,
|
||||
longitude: res.longitude,
|
||||
iconPath: 'https://oss-lock.xhjcn.ltd/mp/icon_address.png',
|
||||
width: '48rpx',
|
||||
height: '48rpx'
|
||||
}
|
||||
]
|
||||
that.show = true
|
||||
const { code, data: result } = await getGeocodeAddress({
|
||||
latitude: that.latitude,
|
||||
longitude: that.longitude
|
||||
})
|
||||
if (code === 0) {
|
||||
that.address = result.addr
|
||||
const position = {
|
||||
...result,
|
||||
latitude: that.latitude,
|
||||
longitude: that.longitude
|
||||
}
|
||||
console.log('获取地理位置信息', that.currentLockInfo)
|
||||
that.updateCurrentLockInfo({
|
||||
...that.currentLockInfo,
|
||||
position
|
||||
})
|
||||
console.log('获取地理位置信息', that.currentLockInfo)
|
||||
}
|
||||
},
|
||||
fail(res) {
|
||||
console.log('获取地理位置信息失败', res)
|
||||
if (res.errMsg === 'getLocation:fail auth deny') {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '拒绝授权将无法使用定位功能',
|
||||
confirmText: '去授权',
|
||||
cancelText: '跳过',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
} else {
|
||||
that.routeJump({
|
||||
type: 'redirectTo',
|
||||
name: 'bindLock'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
} else if (res.errMsg === 'getLocation:fail system permission denied') {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '定位失败,请打开微信的位置权限',
|
||||
confirmText: '去打开',
|
||||
cancelText: '跳过',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
uni.openAppAuthorizeSetting()
|
||||
} else {
|
||||
that.routeJump({
|
||||
type: 'redirectTo',
|
||||
name: 'bindLock'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '获取地理位置信息失败',
|
||||
confirmText: '重试',
|
||||
cancelText: '跳过',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
that.getLocation()
|
||||
} else {
|
||||
that.routeJump({
|
||||
type: 'redirectTo',
|
||||
name: 'bindLock'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.map {
|
||||
width: 750rpx;
|
||||
height: 650rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
padding: 40rpx 30rpx;
|
||||
font-size: 80rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.explain {
|
||||
padding: 20rpx 30rpx 0 30rpx;
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.view-address {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 690rpx;
|
||||
color: #c4c4c4;
|
||||
font-size: 32rpx;
|
||||
margin: 0 30rpx;
|
||||
border-bottom: #63b8af 3rpx solid;
|
||||
|
||||
.address {
|
||||
width: 690rpx;
|
||||
text-align: left;
|
||||
word-break: break-all;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
width: 600rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 75rpx;
|
||||
position: fixed;
|
||||
bottom: calc(30rpx + env(safe-area-inset-bottom));
|
||||
|
||||
.skip {
|
||||
width: 225rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
font-size: 36rpx;
|
||||
border-radius: 64rpx;
|
||||
border: 3rpx solid #63b8af;
|
||||
}
|
||||
|
||||
.confirm {
|
||||
border-radius: 64rpx;
|
||||
color: #ffffff;
|
||||
background-color: #63b8af;
|
||||
width: 225rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -39,7 +39,7 @@
|
||||
<up-icon
|
||||
name="question-circle-fill"
|
||||
@click="tip"
|
||||
size="52"
|
||||
size="52rpx"
|
||||
color="rgba(0,0,0,0.35)"
|
||||
></up-icon>
|
||||
</view>
|
||||
|
||||
@ -38,9 +38,11 @@
|
||||
const time = ref(0)
|
||||
|
||||
onMounted(async () => {
|
||||
// #ifdef MP-WEIXIN
|
||||
const accountInfo = uni.getAccountInfoSync()
|
||||
getApp().globalData.appid = accountInfo.miniProgram.appId
|
||||
getApp().globalData.envVersion = accountInfo.miniProgram.envVersion
|
||||
// #endif
|
||||
|
||||
const result = await passthrough({
|
||||
request_method: 'POST',
|
||||
|
||||
@ -218,9 +218,11 @@
|
||||
title: '加载中',
|
||||
mask: true
|
||||
})
|
||||
// #ifdef MP-WEIXIN
|
||||
const accountInfo = uni.getAccountInfoSync()
|
||||
getApp().globalData.appid = accountInfo.miniProgram.appId
|
||||
getApp().globalData.envVersion = accountInfo.miniProgram.envVersion
|
||||
// #endif
|
||||
this.deviceInfo = await this.getDeviceInfo()
|
||||
const token = getStorage('token')
|
||||
if (token) {
|
||||
@ -243,9 +245,12 @@
|
||||
await this.homeLogin()
|
||||
this.pending = false
|
||||
uni.hideLoading()
|
||||
console.log('登录成功')
|
||||
}
|
||||
// #ifdef MP-WEIXIN
|
||||
const _data = JSON.parse(JSON.stringify(data))
|
||||
this.shareJump(_data)
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
timeFormat,
|
||||
@ -403,6 +408,7 @@
|
||||
homeLogin() {
|
||||
const that = this
|
||||
return new Promise(resolve => {
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
async success(loginRes) {
|
||||
@ -437,6 +443,8 @@
|
||||
resolve(false)
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
resolve(false)
|
||||
})
|
||||
},
|
||||
changeRadio() {
|
||||
|
||||
@ -172,7 +172,11 @@
|
||||
></image>
|
||||
<view>掌静脉</view>
|
||||
</view>
|
||||
<view class="menu-main-view" @click="$basic.routeJump({ name: 'p2pPlayer' })">
|
||||
<view
|
||||
v-if="$bluetooth.currentLockInfo.transportType === transportType.TRANSPORT_TENCENT_YUN"
|
||||
class="menu-main-view"
|
||||
@click="$basic.routeJump({ name: 'p2pPlayer' })"
|
||||
>
|
||||
<image
|
||||
class="menu-main-image transform-scale-140"
|
||||
src="https://oss-lock.xhjcn.ltd/mp/icon_control.png"
|
||||
@ -191,6 +195,7 @@
|
||||
<view>授权管理员</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="$bluetooth.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN"
|
||||
class="menu-main-view transform-scale-105"
|
||||
@click="$basic.routeJump({ name: 'recordList' })"
|
||||
>
|
||||
@ -201,6 +206,7 @@
|
||||
<view>操作记录</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="$bluetooth.currentLockInfo.transportType === transportType.TRANSPORT_TENCENT_YUN"
|
||||
class="menu-main-view transform-scale-105"
|
||||
@click="$basic.routeJump({ name: 'videoLog' })"
|
||||
>
|
||||
@ -208,7 +214,7 @@
|
||||
class="menu-main-image"
|
||||
src="https://oss-lock.xhjcn.ltd/mp/icon_record.png"
|
||||
></image>
|
||||
<view>视频日志</view>
|
||||
<view>门锁记录</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="$bluetooth.currentLockInfo.keyRight === 1"
|
||||
@ -223,6 +229,7 @@
|
||||
</view>
|
||||
<view
|
||||
class="menu-main-view transform-scale-105"
|
||||
v-if="$bluetooth.currentLockInfo.transportType === transportType.TRANSPORT_TENCENT_YUN"
|
||||
@click="$basic.routeJump({ name: 'authorizeWechat' })"
|
||||
>
|
||||
<image
|
||||
@ -279,6 +286,7 @@
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { getLockDetailRequest, getLockNetTokenRequest } from '@/api/lock'
|
||||
import { deleteKeyRequest } from '@/api/key'
|
||||
import { transportType } from '@/constant/transportType'
|
||||
|
||||
const $bluetooth = useBluetoothStore()
|
||||
const $basic = useBasicStore()
|
||||
@ -354,14 +362,6 @@
|
||||
openTime: parseInt(new Date().getTime() / 1000, 10) + time.value,
|
||||
onlineToken: onlineToken.value
|
||||
})
|
||||
$bluetooth
|
||||
.syncRecord({
|
||||
keyId: $bluetooth.currentLockInfo.keyId.toString(),
|
||||
uid: $user.userInfo.uid.toString()
|
||||
})
|
||||
.then(() => {
|
||||
$bluetooth.closeBluetoothConnection()
|
||||
})
|
||||
if (type === 'open') {
|
||||
uni.reportEvent('open_door', {
|
||||
result: code,
|
||||
@ -374,6 +374,14 @@
|
||||
})
|
||||
}
|
||||
if (code === 0) {
|
||||
$bluetooth
|
||||
.syncRecord({
|
||||
keyId: $bluetooth.currentLockInfo.keyId.toString(),
|
||||
uid: $user.userInfo.uid.toString()
|
||||
})
|
||||
.then(() => {
|
||||
$bluetooth.closeBluetoothConnection()
|
||||
})
|
||||
show.value = true
|
||||
typeValue.value = type
|
||||
setTimeout(() => {
|
||||
|
||||
@ -1,219 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view v-if="list.length === 0 && requestFinished">
|
||||
<image
|
||||
class="empty-list"
|
||||
src="https://oss-lock.xhjcn.ltd/mp/background_empty_list.png"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="empty-list-text">暂无数据</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view v-for="(item, index) in list" :key="index" class="mt-4">
|
||||
<view>{{ item.date }}</view>
|
||||
<view class="mt-2 flex flex-wrap gap-[19rpx]">
|
||||
<view v-for="video in item.recordList" :key="video.recordId" @click="handleVideo(video)">
|
||||
<image :src="video.imagesUrl" class="w-224 h-224 rounded-xl relative" mode="aspectFill">
|
||||
<view v-if="type === 'select'" class="absolute inset-0 bg-black bg-opacity-30">
|
||||
<image
|
||||
v-if="selectList.includes(video)"
|
||||
class="w-40 h-40 top-16 right-16 absolute"
|
||||
src="https://oss-lock.xhjcn.ltd/mp/icon_select.png"
|
||||
></image>
|
||||
<image
|
||||
v-else
|
||||
class="w-40 h-40 top-16 right-16 absolute"
|
||||
src="https://oss-lock.xhjcn.ltd/mp/icon_not_select.png"
|
||||
></image>
|
||||
</view>
|
||||
<view
|
||||
v-else
|
||||
class="absolute inset-0 bg-black bg-opacity-30 flex items-center justify-center"
|
||||
>
|
||||
<up-icon name="play-right-fill" color="#ffffff" size="40"></up-icon>
|
||||
</view>
|
||||
</image>
|
||||
<view class="text-xs">{{ timeFormat(video.operateDate, 'yyyy-mm-dd hh:MM') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { timeFormat } from 'uview-plus'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useBasicStore } from '@/stores/basic'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { getVideoList } from '@/api/sdk'
|
||||
|
||||
const $basic = useBasicStore()
|
||||
const $bluetooth = useBluetoothStore()
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: 'list'
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['change'])
|
||||
|
||||
const requestFinished = ref(false)
|
||||
|
||||
const list = ref([])
|
||||
const selectList = ref([])
|
||||
|
||||
onMounted(async () => {
|
||||
await getList()
|
||||
requestFinished.value = true
|
||||
})
|
||||
|
||||
const getList = async () => {
|
||||
const res = await getVideoList({
|
||||
lockId: $bluetooth.currentLockInfo.lockId
|
||||
})
|
||||
if (res.code === 0) {
|
||||
// list.value = res.data
|
||||
|
||||
list.value = [
|
||||
{
|
||||
date: '2025-04-08',
|
||||
recordList: [
|
||||
{
|
||||
recordId: 1,
|
||||
imagesUrl:
|
||||
'https://q0.itc.cn/q_70/images03/20250331/84b2646fc92d4ea0b12f1b134652c807.jpeg',
|
||||
videoUrl:
|
||||
'https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-360p.mp4',
|
||||
operateDate: '1745423939000'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
date: '2025-04-07',
|
||||
recordList: [
|
||||
{
|
||||
recordId: 2,
|
||||
imagesUrl:
|
||||
'https://q0.itc.cn/q_70/images03/20250331/84b2646fc92d4ea0b12f1b134652c807.jpeg',
|
||||
videoUrl: 'http://vjs.zencdn.net/v/oceans.mp4',
|
||||
operateDate: '1745423939000'
|
||||
},
|
||||
{
|
||||
recordId: 3,
|
||||
imagesUrl:
|
||||
'https://q0.itc.cn/q_70/images03/20250331/84b2646fc92d4ea0b12f1b134652c807.jpeg',
|
||||
videoUrl: 'http://www.w3school.com.cn/example/html5/mov_bbb.mp4',
|
||||
operateDate: '1745423939000'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
date: '2025-04-06',
|
||||
recordList: [
|
||||
{
|
||||
recordId: 4,
|
||||
imagesUrl:
|
||||
'https://q0.itc.cn/q_70/images03/20250331/84b2646fc92d4ea0b12f1b134652c807.jpeg',
|
||||
videoUrl: 'https://www.w3schools.com/html/movie.mp4',
|
||||
operateDate: '1745423939000'
|
||||
},
|
||||
{
|
||||
recordId: 5,
|
||||
imagesUrl:
|
||||
'https://q0.itc.cn/q_70/images03/20250331/84b2646fc92d4ea0b12f1b134652c807.jpeg',
|
||||
videoUrl: 'https://media.w3.org/2010/05/sintel/trailer.mp4',
|
||||
operateDate: '1745423939000'
|
||||
},
|
||||
{
|
||||
recordId: 6,
|
||||
imagesUrl:
|
||||
'https://q0.itc.cn/q_70/images03/20250331/84b2646fc92d4ea0b12f1b134652c807.jpeg',
|
||||
videoUrl:
|
||||
'https://stream7.iqilu.com/10339/upload_transcode/202002/09/20200209105011F0zPoYzHry.mp4',
|
||||
operateDate: '1745423939000'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
date: '2025-04-05',
|
||||
recordList: [
|
||||
{
|
||||
recordId: 7,
|
||||
imagesUrl:
|
||||
'https://q0.itc.cn/q_70/images03/20250331/84b2646fc92d4ea0b12f1b134652c807.jpeg',
|
||||
videoUrl: 'http://vjs.zencdn.net/v/oceans.mp4',
|
||||
operateDate: '1745423939000'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleVideo = item => {
|
||||
if (props.type === 'select') {
|
||||
const isExist = selectList.value.find(data => data.recordId === item.recordId)
|
||||
if (isExist) {
|
||||
selectList.value = selectList.value.filter(data => data.recordId !== item.recordId)
|
||||
} else {
|
||||
selectList.value.push(item)
|
||||
}
|
||||
emit('change', selectList.value)
|
||||
} else {
|
||||
$basic.routeJump({
|
||||
type: props.type === 'list' ? 'navigateTo' : 'redirectTo',
|
||||
name: 'videoDetail',
|
||||
params: {
|
||||
video: JSON.stringify(item)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const selectAll = isSelectAll => {
|
||||
if (props.type === 'select') {
|
||||
if (isSelectAll) {
|
||||
list.value.forEach(item => {
|
||||
item.recordList.forEach(video => {
|
||||
selectList.value.push(video)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
selectList.value = []
|
||||
}
|
||||
emit('change', selectList.value)
|
||||
}
|
||||
}
|
||||
|
||||
const refresh = () => {
|
||||
getList()
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
refresh,
|
||||
selectAll
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.empty-list {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
margin: 300rpx auto 20rpx 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.empty-list-text {
|
||||
font-size: 32rpx;
|
||||
color: #999999;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@ -1,145 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="flex justify-between items-center px-2.5 py-2">
|
||||
<view>已选{{ selectList.length }}项</view>
|
||||
<view @click="selectAll">{{ isSelectAll ? '取消全选' : '全选' }}</view>
|
||||
</view>
|
||||
<view class="mx-2.5 pb-25">
|
||||
<VideoList ref="videoListRef" type="select" @change="handleChange" />
|
||||
</view>
|
||||
<view class="fixed bottom-0 flex justify-center w-full w-300 mx-auto bg-white">
|
||||
<view class="flex justify-between w-200 mr-4 h-160">
|
||||
<view @click="handleDownload">
|
||||
<view class="flex flex-col items-center">
|
||||
<image
|
||||
src="https://oss-lock.xhjcn.ltd/mp/icon_video_download.png"
|
||||
class="w-50 h-50"
|
||||
></image>
|
||||
<view class="mt-2">下载</view>
|
||||
</view>
|
||||
</view>
|
||||
<view @click="handleDelete">
|
||||
<view class="flex flex-col items-center">
|
||||
<image
|
||||
src="https://oss-lock.xhjcn.ltd/mp/icon_video_delete.png"
|
||||
class="w-50 h-50"
|
||||
></image>
|
||||
<view class="mt-2">删除</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getCurrentInstance, ref } from 'vue'
|
||||
import VideoList from './VideoList.vue'
|
||||
import { deleteVideo } from '@/api/sdk'
|
||||
|
||||
const instance = getCurrentInstance().proxy
|
||||
const eventChannel = instance.getOpenerEventChannel()
|
||||
|
||||
const videoListRef = ref(null)
|
||||
|
||||
const isSelectAll = ref(false)
|
||||
|
||||
const selectList = ref([])
|
||||
|
||||
const pending = ref(false)
|
||||
|
||||
const handleChange = list => {
|
||||
selectList.value = list
|
||||
}
|
||||
|
||||
const selectAll = () => {
|
||||
isSelectAll.value = !isSelectAll.value
|
||||
videoListRef.value.selectAll(isSelectAll.value)
|
||||
}
|
||||
|
||||
const handleDownload = () => {
|
||||
console.log('下载')
|
||||
if (selectList.value.length === 0) {
|
||||
uni.showToast({
|
||||
title: '请选择要下载的视频',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (selectList.value.length > 1) {
|
||||
uni.showToast({
|
||||
title: '视频暂不支持批量下载',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '下载中'
|
||||
})
|
||||
pending.value = true
|
||||
const url = selectList.value[0].videoUrl
|
||||
uni.downloadFile({
|
||||
url,
|
||||
success: res => {
|
||||
uni.saveVideoToPhotosAlbum({
|
||||
filePath: res.tempFilePath,
|
||||
success: () => {
|
||||
uni.hideLoading()
|
||||
pending.value = false
|
||||
uni.showToast({
|
||||
title: '下载成功',
|
||||
icon: 'none'
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.hideLoading()
|
||||
pending.value = false
|
||||
uni.showToast({
|
||||
title: '下载失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.hideLoading()
|
||||
pending.value = false
|
||||
uni.showToast({
|
||||
title: '下载失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleDelete = async () => {
|
||||
if (selectList.value.length === 0) {
|
||||
uni.showToast({
|
||||
title: '请选择要删除的视频',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '删除中'
|
||||
})
|
||||
pending.value = true
|
||||
const idList = selectList.value.map(item => item.recordId)
|
||||
const { code, message } = await deleteVideo(idList)
|
||||
uni.hideLoading()
|
||||
pending.value = false
|
||||
if (code === 0) {
|
||||
videoListRef.value.refresh()
|
||||
eventChannel.emit('refresh')
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'success'
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,51 +1,423 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="bg-#f5f4f8 flex items-center mx-2.5 my-4 p-4 rounded-xl shadow-sm">
|
||||
<view>
|
||||
<view>3天滚动储存</view>
|
||||
<view class="text-#999999 mt-2 text-sm">
|
||||
{{ appName }}已为本设备免费提供3天滚动视频储存服务
|
||||
<view class="m-4" v-if="info">
|
||||
<swiper indicator-dots autoplay circular class="h-195" @click="toWebview">
|
||||
<swiper-item>
|
||||
<image
|
||||
mode="widthFix"
|
||||
src="https://xhj-starlock.oss-cn-shenzhen.aliyuncs.com/mp/swiper_video_ai.png"
|
||||
class="w-full rounded-2xl"
|
||||
/>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
<image
|
||||
mode="widthFix"
|
||||
src="https://xhj-starlock.oss-cn-shenzhen.aliyuncs.com/mp/swiper_video_log.png"
|
||||
class="w-full rounded-2xl"
|
||||
/>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<view class="text-sm mt-2 flex mx-2" :style="{ color: color }">
|
||||
<div class="i-solar:cloud-upload-linear size-40 mr-1"></div>
|
||||
{{ info.desc }}
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view
|
||||
v-if="deviceInfo"
|
||||
scroll-y="true"
|
||||
:lower-threshold="100"
|
||||
:style="{ height: deviceInfo.screenHeight - deviceInfo.safeArea.top - 145 + 'px' }"
|
||||
:refresher-enabled="true"
|
||||
@refresherrefresh="onRefresh"
|
||||
@scrolltolower="onScrollToLower"
|
||||
:refresher-triggered="refresherTriggered"
|
||||
>
|
||||
<view class="pb-40">
|
||||
<view v-if="groupedList.length === 0 && requestFlag">
|
||||
<image
|
||||
class="w-[150rpx] h-[150rpx] mt-[300rpx] mx-auto mb-[20rpx] ml-[50%] -translate-x-1/2"
|
||||
src="https://oss-lock.xhjcn.ltd/mp/background_empty_list.png"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="text-[32rpx] text-[#999999] text-center">暂无数据</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view v-for="group in groupedList" :key="group.date" class="mb-2">
|
||||
<view class="px-4 py-2 text-gray-600 text-sm font-medium font-bold">
|
||||
{{ group.date }}
|
||||
</view>
|
||||
<view
|
||||
v-for="item in group.items"
|
||||
:key="item.event_id"
|
||||
class="px-4 py-1 border-b border-gray-200 text-base"
|
||||
>
|
||||
<view class="mx-2">
|
||||
<view class="flex items-start">
|
||||
<view class="bg-#63b8af size-15 rounded-full mr-2 mt-1.5"></view>
|
||||
<view class="w-full">
|
||||
<view class="font-bold flex justify-between w-full">
|
||||
<view>{{ item.event_type_name }}</view>
|
||||
<view
|
||||
class="i-material-symbols:more-horiz text-#999999 size-45 font-bold"
|
||||
@click="operateEvent(item.event_id)"
|
||||
></view>
|
||||
</view>
|
||||
<view class="text-sm text-#999999 mt-0.5">
|
||||
{{ formatTime(item.event_time) }}
|
||||
</view>
|
||||
<view class="font-bold mt-1 text-#999999">
|
||||
{{ item.text }}
|
||||
</view>
|
||||
<view v-if="item.video !== '' && item.video_expire_at > Date.now() / 1000">
|
||||
<video
|
||||
:id="`video-${item.event_id}`"
|
||||
:src="item.video"
|
||||
class="w-300"
|
||||
@click="playVideoFullscreen(item.event_id)"
|
||||
@fullscreenchange="onFullscreenChange(item.event_id, $event)"
|
||||
@play="onVideoPlay(item.event_id)"
|
||||
@pause="onVideoPause(item.event_id)"
|
||||
controls
|
||||
show-fullscreen-btn
|
||||
></video>
|
||||
<view class="text-sm text-#999999 mt-1">
|
||||
{{ formatRemainingTime(item.video_expire_at) }}
|
||||
</view>
|
||||
</view>
|
||||
<view v-else-if="item.preview_image !== ''">
|
||||
<image :src="item.preview_image" class="w-300" mode="widthFix" />
|
||||
<view v-if="item.video !== ''" class="text-sm text-#999999 mt-1">
|
||||
{{ formatRemainingTime(item.video_expire_at) }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-none whitespace-nowrap mx-1.5">去升级</view>
|
||||
<up-icon name="arrow-right" />
|
||||
</view>
|
||||
<view class="mx-2.5 pb-10">
|
||||
<view class="flex items-center justify-between">
|
||||
<view>全部视频</view>
|
||||
<image
|
||||
src="https://oss-lock.xhjcn.ltd/mp/icon_edit.png"
|
||||
@click="handleEdit"
|
||||
class="w-48 h-48"
|
||||
/>
|
||||
</view>
|
||||
<VideoList ref="videoListRef" />
|
||||
</scroll-view>
|
||||
<view
|
||||
v-if="list.length > 0"
|
||||
class="fixed bottom-70 right-16 rounded-full bg-red p-2"
|
||||
@click="resetLog"
|
||||
>
|
||||
<div class="i-material-symbols:delete-outline-rounded size-70 color-white"></div>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import env from '@/config/env'
|
||||
import VideoList from './VideoList.vue'
|
||||
import { onMounted, ref, computed } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { passthrough } from '@/api/sdk'
|
||||
import { useBasicStore } from '@/stores/basic'
|
||||
|
||||
const $bluetooth = useBluetoothStore()
|
||||
const $basic = useBasicStore()
|
||||
const info = ref()
|
||||
|
||||
const pageSize = 50
|
||||
const list = ref([])
|
||||
const pageNo = ref(1)
|
||||
const total = ref(0)
|
||||
const refresherTriggered = ref(false)
|
||||
|
||||
const requestFlag = ref(false)
|
||||
|
||||
const deviceInfo = ref(null)
|
||||
const fullscreenVideoId = ref(null)
|
||||
const isFullscreenChanging = ref(false)
|
||||
const currentPlayingVideoId = ref(null)
|
||||
|
||||
const appName = ref('')
|
||||
const videoListRef = ref(null)
|
||||
onMounted(async () => {
|
||||
appName.value = await env[await getApp().globalData.getEnvConfig()].appName
|
||||
deviceInfo.value = await $basic.getDeviceInfo()
|
||||
await Promise.all([getInfo(), getList()])
|
||||
|
||||
requestFlag.value = true
|
||||
})
|
||||
|
||||
const handleEdit = () => {
|
||||
$basic.routeJump({
|
||||
name: 'videoEdit',
|
||||
events: {
|
||||
refresh: () => {
|
||||
videoListRef.value.refresh()
|
||||
onShow(() => {
|
||||
if (requestFlag.value) {
|
||||
getInfo()
|
||||
}
|
||||
})
|
||||
|
||||
const operateEvent = eventId => {
|
||||
uni.showActionSheet({
|
||||
itemList: ['删除'],
|
||||
success: ({ tapIndex }) => {
|
||||
if (tapIndex === 0) {
|
||||
deleteEvent(eventId)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const toWebview = () => {
|
||||
$basic.routeJump({
|
||||
name: 'webview',
|
||||
params: {
|
||||
url: encodeURIComponent('https://www.baidu.com')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const resetLog = async () => {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定删除所有记录吗?',
|
||||
success: async ({ confirm }) => {
|
||||
if (confirm) {
|
||||
if (confirm) {
|
||||
const { code, message } = await passthrough({
|
||||
request_method: 'POST',
|
||||
request_uri: '/api/v1/cloudStorage/clearStorageEvent',
|
||||
post_args: { lockId: $bluetooth.currentLockInfo.lockId }
|
||||
})
|
||||
|
||||
if (code === 0) {
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'none'
|
||||
})
|
||||
await getList()
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
const deleteEvent = async eventId => {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定删除该记录吗?',
|
||||
success: async ({ confirm }) => {
|
||||
if (confirm) {
|
||||
const { code, message } = await passthrough({
|
||||
request_method: 'POST',
|
||||
request_uri: '/api/v1/cloudStorage/delStorageEvent',
|
||||
post_args: { eventId }
|
||||
})
|
||||
|
||||
if (code === 0) {
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'none'
|
||||
})
|
||||
await getList()
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const formatDate = timestamp => {
|
||||
const date = new Date(timestamp * 1000)
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
|
||||
const formatTime = timestamp => {
|
||||
const date = new Date(timestamp * 1000)
|
||||
const hours = String(date.getHours()).padStart(2, '0')
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0')
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0')
|
||||
return `${hours}:${minutes}:${seconds}`
|
||||
}
|
||||
|
||||
const formatRemainingTime = expireTimestamp => {
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
const diff = expireTimestamp - now
|
||||
|
||||
if (diff <= 0) {
|
||||
return '视频已过期'
|
||||
}
|
||||
|
||||
const days = Math.floor(diff / (24 * 60 * 60))
|
||||
const hours = Math.floor((diff % (24 * 60 * 60)) / (60 * 60))
|
||||
const minutes = Math.floor((diff % (60 * 60)) / 60)
|
||||
|
||||
let result = '视频'
|
||||
|
||||
if (days > 0) {
|
||||
result += `${days}天`
|
||||
}
|
||||
if (hours > 0) {
|
||||
result += `${hours}小时`
|
||||
}
|
||||
if (minutes > 0 && days === 0) {
|
||||
result += `${minutes}分钟`
|
||||
}
|
||||
|
||||
result += '后过期'
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
const groupedList = computed(() => {
|
||||
const groups = []
|
||||
const dateMap = new Map()
|
||||
|
||||
list.value.forEach(item => {
|
||||
const dateKey = formatDate(item.event_time)
|
||||
|
||||
if (!dateMap.has(dateKey)) {
|
||||
const newGroup = {
|
||||
date: dateKey,
|
||||
items: []
|
||||
}
|
||||
groups.push(newGroup)
|
||||
dateMap.set(dateKey, newGroup)
|
||||
}
|
||||
|
||||
dateMap.get(dateKey).items.push(item)
|
||||
})
|
||||
|
||||
return groups
|
||||
})
|
||||
|
||||
const color = computed(() => {
|
||||
if (info.value?.status === 1) {
|
||||
return '#63b8af'
|
||||
}
|
||||
if (info.value?.status === 2) {
|
||||
return 'red'
|
||||
}
|
||||
|
||||
return '#999999'
|
||||
})
|
||||
|
||||
const onRefresh = async () => {
|
||||
refresherTriggered.value = true
|
||||
pageNo.value = 1
|
||||
await getList()
|
||||
refresherTriggered.value = false
|
||||
}
|
||||
|
||||
const onScrollToLower = async () => {
|
||||
if (list.value.length < total.value) {
|
||||
getList(pageNo.value + 1)
|
||||
}
|
||||
}
|
||||
|
||||
const getInfo = async () => {
|
||||
const { code, data, message } = await passthrough({
|
||||
request_method: 'POST',
|
||||
request_uri: '/api/v1/cloudStorage/getStorageServiceInfo',
|
||||
post_args: {
|
||||
lockId: $bluetooth.currentLockInfo.lockId
|
||||
}
|
||||
})
|
||||
|
||||
if (code === 0) {
|
||||
info.value = data
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const getList = async (pageNo = 1) => {
|
||||
if (pageNo > 1 && (pageNo - 1) * pageSize >= total.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const { code, data, message } = await passthrough({
|
||||
request_method: 'POST',
|
||||
request_uri: '/api/v1/cloudStorage/getStorageEventList',
|
||||
post_args: {
|
||||
lockId: $bluetooth.currentLockInfo.lockId,
|
||||
pageNo,
|
||||
pageSize
|
||||
}
|
||||
})
|
||||
|
||||
if (code === 0) {
|
||||
if (pageNo === 1) {
|
||||
list.value = data.list
|
||||
} else {
|
||||
list.value = [...list.value, ...data.list]
|
||||
}
|
||||
total.value = data.total
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
return { code, data, message }
|
||||
}
|
||||
|
||||
const playVideoFullscreen = eventId => {
|
||||
if (fullscreenVideoId.value === eventId) {
|
||||
return
|
||||
}
|
||||
|
||||
if (isFullscreenChanging.value) {
|
||||
return
|
||||
}
|
||||
|
||||
if (currentPlayingVideoId.value && currentPlayingVideoId.value !== eventId) {
|
||||
const currentVideoContext = uni.createVideoContext(`video-${currentPlayingVideoId.value}`)
|
||||
currentVideoContext.pause()
|
||||
}
|
||||
|
||||
const videoId = `video-${eventId}`
|
||||
const videoContext = uni.createVideoContext(videoId)
|
||||
|
||||
isFullscreenChanging.value = true
|
||||
currentPlayingVideoId.value = eventId
|
||||
videoContext.play()
|
||||
|
||||
setTimeout(() => {
|
||||
if (fullscreenVideoId.value !== eventId) {
|
||||
videoContext.requestFullScreen({
|
||||
direction: 0
|
||||
})
|
||||
}
|
||||
setTimeout(() => {
|
||||
isFullscreenChanging.value = false
|
||||
}, 500)
|
||||
}, 300)
|
||||
}
|
||||
|
||||
const onFullscreenChange = (eventId, event) => {
|
||||
if (event.detail.fullScreen) {
|
||||
fullscreenVideoId.value = eventId
|
||||
} else {
|
||||
fullscreenVideoId.value = null
|
||||
}
|
||||
}
|
||||
|
||||
const onVideoPlay = eventId => {
|
||||
if (currentPlayingVideoId.value && currentPlayingVideoId.value !== eventId) {
|
||||
const currentVideoContext = uni.createVideoContext(`video-${currentPlayingVideoId.value}`)
|
||||
currentVideoContext.pause()
|
||||
}
|
||||
currentPlayingVideoId.value = eventId
|
||||
}
|
||||
|
||||
const onVideoPause = eventId => {
|
||||
if (currentPlayingVideoId.value === eventId) {
|
||||
currentPlayingVideoId.value = null
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
"
|
||||
name="checkbox-mark"
|
||||
color="#2a85ec"
|
||||
size="40"
|
||||
size="40rpx"
|
||||
></up-icon>
|
||||
</view>
|
||||
<view class="flex-1">
|
||||
@ -70,7 +70,7 @@
|
||||
"
|
||||
name="checkbox-mark"
|
||||
color="#2a85ec"
|
||||
size="40"
|
||||
size="40rpx"
|
||||
></up-icon>
|
||||
</view>
|
||||
<view class="flex-1">
|
||||
@ -122,7 +122,7 @@
|
||||
"
|
||||
name="checkbox-mark"
|
||||
color="#2a85ec"
|
||||
size="40"
|
||||
size="40rpx"
|
||||
></up-icon>
|
||||
</view>
|
||||
<view class="flex-1">
|
||||
@ -174,7 +174,7 @@
|
||||
"
|
||||
name="checkbox-mark"
|
||||
color="#2a85ec"
|
||||
size="40"
|
||||
size="40rpx"
|
||||
></up-icon>
|
||||
</view>
|
||||
<view class="flex-1">
|
||||
|
||||
@ -49,7 +49,7 @@
|
||||
@click="toJump(null)"
|
||||
class="flex items-center justify-center bg-white shadow-sm rounded-md pos-fixed bottom-[calc(env(safe-area-inset-bottom)+48rpx)] w-686 mx-4 h-100"
|
||||
><view class="flex items-center">
|
||||
<up-icon name="plus-circle-fill" color="#002ce5" size="50"></up-icon
|
||||
<up-icon name="plus-circle-fill" color="#002ce5" size="50rpx"></up-icon
|
||||
><view class="text-lg text-#63b8af ml-2 font-bold">胁迫指纹</view>
|
||||
</view></view
|
||||
>
|
||||
|
||||
@ -105,12 +105,6 @@
|
||||
<up-icon name="arrow-right"></up-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="py-3 px-4 bg-white flex items-center justify-between text-base">
|
||||
<view>位置信息</view>
|
||||
<view class="flex items-center max-w-400">
|
||||
<view>{{ $bluetooth.currentLockSetting.lockBasicInfo.address }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<ModalInput
|
||||
ref="modalInput"
|
||||
title="请输入名称"
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
:class="[value === 1 ? 'bg-#d9e8fd' : 'bg-#ececec']"
|
||||
>
|
||||
<view class="w-80 h-full flex items-center justify-center">
|
||||
<up-icon name="checkbox-mark" color="#2a85ec" v-if="value === 1" size="40"></up-icon>
|
||||
<up-icon name="checkbox-mark" color="#2a85ec" v-if="value === 1" size="40rpx"></up-icon>
|
||||
</view>
|
||||
<view class="flex-1">
|
||||
<view>小功率:</view>
|
||||
@ -22,7 +22,7 @@
|
||||
:class="[value === 2 ? 'bg-#d9e8fd' : 'bg-#ececec']"
|
||||
>
|
||||
<view class="w-80 h-full flex items-center justify-center">
|
||||
<up-icon name="checkbox-mark" color="#2a85ec" v-if="value === 2" size="40"></up-icon>
|
||||
<up-icon name="checkbox-mark" color="#2a85ec" v-if="value === 2" size="40rpx"></up-icon>
|
||||
</view>
|
||||
<view class="flex-1">
|
||||
<view>中功率:</view>
|
||||
@ -35,7 +35,7 @@
|
||||
:class="[value === 3 ? 'bg-#d9e8fd' : 'bg-#ececec']"
|
||||
>
|
||||
<view class="w-80 h-full flex items-center justify-center">
|
||||
<up-icon name="checkbox-mark" color="#2a85ec" v-if="value === 3" size="40"></up-icon>
|
||||
<up-icon name="checkbox-mark" color="#2a85ec" v-if="value === 3" size="40rpx"></up-icon>
|
||||
</view>
|
||||
<view class="flex-1">
|
||||
<view>大功率:</view>
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
<up-icon
|
||||
name="plus-circle-fill"
|
||||
color="#002ce5"
|
||||
size="50"
|
||||
size="50rpx"
|
||||
v-if="emailList.length < 3"
|
||||
@click="addItem('email')"
|
||||
></up-icon
|
||||
@ -27,7 +27,7 @@
|
||||
<up-icon
|
||||
name="close-circle-fill"
|
||||
color="#858585"
|
||||
size="40"
|
||||
size="40rpx"
|
||||
@click="deleteItem('email', index)"
|
||||
></up-icon>
|
||||
<view class="ml-3">接收者</view>
|
||||
@ -51,7 +51,7 @@
|
||||
<up-icon
|
||||
name="plus-circle-fill"
|
||||
color="#002ce5"
|
||||
size="50"
|
||||
size="50rpx"
|
||||
v-if="smsList.length < 3"
|
||||
@click="addItem('sms')"
|
||||
></up-icon
|
||||
@ -66,7 +66,7 @@
|
||||
<up-icon
|
||||
name="close-circle-fill"
|
||||
color="#858585"
|
||||
size="40"
|
||||
size="40rpx"
|
||||
@click="deleteItem('sms', index)"
|
||||
></up-icon>
|
||||
<view class="ml-3">接收者</view>
|
||||
|
||||
@ -49,7 +49,7 @@
|
||||
@click="toJump(null)"
|
||||
class="flex items-center justify-center bg-white shadow-sm rounded-md pos-fixed bottom-[calc(env(safe-area-inset-bottom)+48rpx)] w-686 mx-4 h-100"
|
||||
><view class="flex items-center">
|
||||
<up-icon name="plus-circle-fill" color="#002ce5" size="50"></up-icon
|
||||
<up-icon name="plus-circle-fill" color="#002ce5" size="50rpx"></up-icon
|
||||
><view class="text-lg text-#63b8af ml-2 font-bold">添加家人</view>
|
||||
</view></view
|
||||
>
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
"
|
||||
name="checkbox-mark"
|
||||
color="#2a85ec"
|
||||
size="40"
|
||||
size="40rpx"
|
||||
></up-icon>
|
||||
</view>
|
||||
<view class="flex-1">
|
||||
@ -64,7 +64,7 @@
|
||||
"
|
||||
name="checkbox-mark"
|
||||
color="#2a85ec"
|
||||
size="40"
|
||||
size="40rpx"
|
||||
></up-icon>
|
||||
</view>
|
||||
<view class="flex-1">
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
:class="[isAllDay === 1 ? 'bg-#d9e8fd' : 'bg-#ececec']"
|
||||
>
|
||||
<view class="w-80 h-full flex items-center justify-center">
|
||||
<up-icon v-if="isAllDay === 1" name="checkbox-mark" color="#2a85ec" size="40"></up-icon>
|
||||
<up-icon v-if="isAllDay === 1" name="checkbox-mark" color="#2a85ec" size="40rpx"></up-icon>
|
||||
</view>
|
||||
<view class="flex-1">
|
||||
<view class="text-lg font-bold" :class="[isAllDay === 1 ? 'text-#2a85ec' : 'text-black']"
|
||||
@ -21,7 +21,7 @@
|
||||
>
|
||||
<view class="flex items-center">
|
||||
<view class="w-80 h-full flex items-center justify-center">
|
||||
<up-icon v-if="isAllDay === 0" name="checkbox-mark" color="#2a85ec" size="40"></up-icon>
|
||||
<up-icon v-if="isAllDay === 0" name="checkbox-mark" color="#2a85ec" size="40rpx"></up-icon>
|
||||
</view>
|
||||
<view class="flex-1">
|
||||
<view class="text-lg font-bold" :class="[isAllDay === 0 ? 'text-#2a85ec' : 'text-black']">
|
||||
|
||||
@ -52,11 +52,6 @@ const pages = [
|
||||
path: '/pages/addDevice/searchDevice',
|
||||
tabBar: false
|
||||
},
|
||||
{
|
||||
name: 'selectAddress',
|
||||
path: '/pages/addDevice/selectAddress',
|
||||
tabBar: false
|
||||
},
|
||||
{
|
||||
name: 'bindLock',
|
||||
path: '/pages/addDevice/bindLock',
|
||||
@ -415,7 +410,7 @@ const pages = [
|
||||
]
|
||||
|
||||
export const useBasicStore = defineStore('basic', {
|
||||
state() {
|
||||
state () {
|
||||
return {
|
||||
// 设备信息
|
||||
deviceInfo: null,
|
||||
@ -429,7 +424,7 @@ export const useBasicStore = defineStore('basic', {
|
||||
// 路由跳转
|
||||
/* data 入参 name string页面名称 type string跳转方式 params object传递参数 delta number返回页面数
|
||||
* 具体入参查看文档 https://www.uviewui.com/js/route.html */
|
||||
routeJump(data) {
|
||||
routeJump (data) {
|
||||
const page = pages.find(page => {
|
||||
return page.name === data.name
|
||||
})
|
||||
@ -458,10 +453,10 @@ export const useBasicStore = defineStore('basic', {
|
||||
}
|
||||
},
|
||||
// 获取当前网络状态
|
||||
getNetworkType() {
|
||||
getNetworkType () {
|
||||
return new Promise(resolve => {
|
||||
uni.getNetworkType({
|
||||
success(res) {
|
||||
success (res) {
|
||||
if (res.networkType === 'none') {
|
||||
uni.showToast({
|
||||
title: '网络访问失败,请检查网络是否正常',
|
||||
@ -472,14 +467,14 @@ export const useBasicStore = defineStore('basic', {
|
||||
}
|
||||
resolve(true)
|
||||
},
|
||||
fail() {
|
||||
fail () {
|
||||
resolve(false)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 获取设备信息
|
||||
getDeviceInfo() {
|
||||
getDeviceInfo () {
|
||||
const that = this
|
||||
return new Promise(resolve => {
|
||||
if (that.deviceInfo?.model) {
|
||||
@ -487,18 +482,18 @@ export const useBasicStore = defineStore('basic', {
|
||||
return
|
||||
}
|
||||
uni.getSystemInfo({
|
||||
success(res) {
|
||||
success (res) {
|
||||
that.deviceInfo = res
|
||||
resolve(that.deviceInfo)
|
||||
},
|
||||
fail() {
|
||||
fail () {
|
||||
resolve({})
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 获取胶囊信息
|
||||
getButtonInfo() {
|
||||
getButtonInfo () {
|
||||
return new Promise(resolve => {
|
||||
if (this.buttonInfo?.top) {
|
||||
resolve(this.buttonInfo)
|
||||
@ -509,7 +504,7 @@ export const useBasicStore = defineStore('basic', {
|
||||
})
|
||||
},
|
||||
// 计算字符串长度
|
||||
calculateStringTotalWidth(str) {
|
||||
calculateStringTotalWidth (str) {
|
||||
let totalWidth = 0
|
||||
// 遍历字符串中的每一个字符
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
@ -526,10 +521,10 @@ export const useBasicStore = defineStore('basic', {
|
||||
return totalWidth
|
||||
},
|
||||
// 回退页面并弹出toast提示
|
||||
backAndToast(message, delta = 1) {
|
||||
backAndToast (message, delta = 1) {
|
||||
uni.navigateBack({
|
||||
delta,
|
||||
complete() {
|
||||
complete () {
|
||||
setTimeout(() => {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
@ -540,7 +535,7 @@ export const useBasicStore = defineStore('basic', {
|
||||
})
|
||||
},
|
||||
// 分享跳转
|
||||
shareJump(data = this.shareConfig) {
|
||||
shareJump (data = this.shareConfig) {
|
||||
if (data.path) {
|
||||
const target = data.path.split('/')
|
||||
if (target.length > 1) {
|
||||
@ -568,7 +563,7 @@ export const useBasicStore = defineStore('basic', {
|
||||
}
|
||||
this.shareConfig = data
|
||||
|
||||
function getParams(params) {
|
||||
function getParams (params) {
|
||||
let paramStr = ''
|
||||
Object.keys(params).forEach(item => {
|
||||
if (paramStr === '') {
|
||||
|
||||
@ -898,6 +898,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
checkSetting() {
|
||||
const that = this
|
||||
return new Promise(resolve => {
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.getSetting({
|
||||
async success(res) {
|
||||
const bluetooth = res.authSetting['scope.bluetooth']
|
||||
@ -924,6 +925,8 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
resolve(false)
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
resolve(false)
|
||||
})
|
||||
},
|
||||
// 连接蓝牙设备+获取设备服务+获取设备特征值
|
||||
@ -1049,15 +1052,17 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
// 断开蓝牙连接
|
||||
closeBluetoothConnection() {
|
||||
const that = this
|
||||
uni.closeBLEConnection({
|
||||
deviceId: that.currentLockInfo.deviceId,
|
||||
success(res) {
|
||||
console.log('断开连接成功', res)
|
||||
},
|
||||
fail(res) {
|
||||
console.log('断开连接失败', res)
|
||||
}
|
||||
})
|
||||
if (that.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN) {
|
||||
uni.closeBLEConnection({
|
||||
deviceId: that.currentLockInfo.deviceId,
|
||||
success(res) {
|
||||
console.log('断开连接成功', res)
|
||||
},
|
||||
fail(res) {
|
||||
console.log('断开连接失败', res)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
// 周数组转换
|
||||
convertWeekdaysToNumber(weekDay) {
|
||||
@ -1343,8 +1348,28 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
}
|
||||
})
|
||||
|
||||
if (code === 0 && data.outputParams) {
|
||||
that.parsingCharacteristicValue(that.hexToArray(data.outputParams))
|
||||
if (code === 0) {
|
||||
if (data.Status === 'action execute success!') {
|
||||
if (data.OutputParams.result === '') {
|
||||
characteristicValueCallback({
|
||||
code: 0,
|
||||
message: `成功,${data.Status}`
|
||||
})
|
||||
} else {
|
||||
const params = that.hexToArray(data.OutputParams.result)
|
||||
console.log('转换后的数据', params)
|
||||
that.parsingCharacteristicValue(params)
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: `命令下发失败,${data.Status}`,
|
||||
icon: 'none'
|
||||
})
|
||||
characteristicValueCallback({
|
||||
code: -10,
|
||||
message: `命令下发失败,${data.Status}`
|
||||
})
|
||||
}
|
||||
} else {
|
||||
characteristicValueCallback({
|
||||
code,
|
||||
@ -1489,7 +1514,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, contentArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
return this.getResult()
|
||||
},
|
||||
// 获取私钥
|
||||
@ -1561,7 +1586,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
return this.getResult()
|
||||
},
|
||||
// md5加密
|
||||
@ -1639,7 +1664,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.getLockStatus, data)
|
||||
},
|
||||
@ -1697,7 +1722,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.getLockStatusInfo, data)
|
||||
},
|
||||
@ -1750,7 +1775,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.getWifiList, data)
|
||||
},
|
||||
@ -1810,12 +1835,12 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||||
mode: 'ecb',
|
||||
output: 'array',
|
||||
padding: 'none'
|
||||
padding: length % 16 === 0 ? 'none' : 'pkcs#5'
|
||||
})
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.distributionNetwork, data)
|
||||
},
|
||||
@ -1952,7 +1977,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
})
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
await this.transportMessage(packageArray, false)
|
||||
this.transportMessage(packageArray, false)
|
||||
return this.getResult(this.addLockUser, data)
|
||||
},
|
||||
// 添加用户
|
||||
@ -2068,7 +2093,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
})
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
await this.transportMessage(packageArray, false)
|
||||
this.transportMessage(packageArray, false)
|
||||
return this.getResult(this.bindLock, data)
|
||||
},
|
||||
// 获取写入结果
|
||||
@ -2557,7 +2582,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.cleanLockUser, data)
|
||||
},
|
||||
@ -2638,7 +2663,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.resetDevice, data)
|
||||
},
|
||||
@ -2727,7 +2752,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.resetLockPassword, data)
|
||||
},
|
||||
@ -2832,7 +2857,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.setLockPassword, data)
|
||||
},
|
||||
@ -2985,7 +3010,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.registerAuthentication, data)
|
||||
},
|
||||
@ -3042,7 +3067,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.registerAuthenticationCancel, data)
|
||||
},
|
||||
@ -3169,7 +3194,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.syncSingleRecord, data)
|
||||
},
|
||||
@ -3271,7 +3296,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.updateAdminPassword, data)
|
||||
},
|
||||
@ -3378,7 +3403,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.transportMessage(packageArray)
|
||||
this.transportMessage(packageArray)
|
||||
|
||||
return this.getResult(this.updateSetting, data)
|
||||
},
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import presetWeapp from 'unocss-preset-weapp'
|
||||
import { extractorAttributify, transformerClass } from 'unocss-preset-weapp/transformer'
|
||||
import presetIcons from '@unocss/preset-icons'
|
||||
|
||||
const { presetWeappAttributify, transformerAttributify } = extractorAttributify()
|
||||
|
||||
@ -8,7 +9,14 @@ export default {
|
||||
// https://github.com/MellowCo/unocss-preset-weapp
|
||||
presetWeapp(),
|
||||
// attributify autocomplete
|
||||
presetWeappAttributify()
|
||||
presetWeappAttributify(),
|
||||
presetIcons({
|
||||
collections: {
|
||||
solar: () => import('@iconify-json/solar/icons.json').then(i => i.default),
|
||||
'material-symbols': () =>
|
||||
import('@iconify-json/material-symbols/icons.json').then(i => i.default)
|
||||
}
|
||||
})
|
||||
],
|
||||
shortcuts: [
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user