This commit is contained in:
103
App.vue
103
App.vue
@@ -1,4 +1,11 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import config from "./common/config";
|
||||||
|
import {
|
||||||
|
showNotification
|
||||||
|
} from "@/utils/notify.js"
|
||||||
|
import ws from "@/utils/websocket.js"; // WebSocket 封装类
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
|
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
|
||||||
*/
|
*/
|
||||||
@@ -12,23 +19,56 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 监听登录成功
|
||||||
|
uni.$on("loginSuccess", () => {
|
||||||
|
|
||||||
|
// 仅在 Android 13+ 才需要
|
||||||
|
if (plus.os.name === "Android" && parseInt(plus.os.version) >= 13) {
|
||||||
|
var permission = "android.permission.POST_NOTIFICATIONS";
|
||||||
|
// 请求权限
|
||||||
|
plus.android.requestPermissions(
|
||||||
|
[permission],
|
||||||
|
(resultObj) => {
|
||||||
|
this.initWebSocket()
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
this.initWebSocket()
|
||||||
|
}
|
||||||
|
})
|
||||||
//只有在基座运行的情况下才能打印看到
|
//只有在基座运行的情况下才能打印看到
|
||||||
const clientInfo = plus.push.getClientInfo()
|
const clientInfo = plus.push.getClientInfo()
|
||||||
|
console.log('clientid:', clientInfo.clientid)
|
||||||
|
|
||||||
|
|
||||||
this.$store.commit('$uStore', {
|
this.$store.commit('$uStore', {
|
||||||
name: 'vuex_push_clientId',
|
name: 'vuex_push_clientId',
|
||||||
value: clientInfo.clientid
|
value: clientInfo.clientid
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听系统通知栏点击事件
|
//监听系统通知栏点击事件
|
||||||
plus.push.addEventListener("click", function(msg) {
|
plus.push.addEventListener("click", function(msg) {
|
||||||
console.log("用户点击了推送消息:", msg);
|
console.log("用户点击了推送消息:", msg);
|
||||||
// msg.payload 就是推送时传的自定义数据
|
if (msg.payload) {
|
||||||
uni.navigateTo({
|
if (msg.payload.type == 100) {
|
||||||
url: "/pages/sys/workbench/earlyWarning/warnDetail",
|
uni.navigateTo({
|
||||||
});
|
url: "/pages/sys/workbench/earlyWarning/warnDetail?item=" + msg.payload.data,
|
||||||
|
});
|
||||||
|
} else if (msg.payload.type == 200) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: "/pages/sys/workbench/order/orderDetail?item=" + msg.payload.data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
// 收到推送(前台透传)
|
||||||
|
// plus.push.addEventListener("receive", function(msg) {
|
||||||
|
// console.log("收到推送消息:", msg);
|
||||||
|
// });
|
||||||
// 设置底部导航栏角标
|
// 设置底部导航栏角标
|
||||||
// uni.setTabBarBadge({
|
// uni.setTabBarBadge({
|
||||||
// index: 0,
|
// index: 0,
|
||||||
@@ -37,6 +77,57 @@
|
|||||||
// uni.removeTabBarBadge({
|
// uni.removeTabBarBadge({
|
||||||
// index: 0
|
// index: 0
|
||||||
// });
|
// });
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initWebSocket() {
|
||||||
|
let url = this.vuex_config.baseUrl +
|
||||||
|
'/resource/websocket?clientid=dab457a1ea14411787c240db05bb0832&Authorization=Bearer ' + this
|
||||||
|
.vuex_token;
|
||||||
|
console.log('t1', url)
|
||||||
|
ws.connect(url)
|
||||||
|
ws.setDispatchHandler(this.handleWsMessage)
|
||||||
|
// this.ws = uni.connectSocket({
|
||||||
|
// url: url, // 鉴权
|
||||||
|
// success: () => console.log("连接请求已发送")
|
||||||
|
// })
|
||||||
|
|
||||||
|
// this.ws.onOpen(() => {
|
||||||
|
// console.log("WebSocket已连接")
|
||||||
|
// })
|
||||||
|
|
||||||
|
// this.ws.onMessage((res) => {
|
||||||
|
// console.log('t1', 1111111111)
|
||||||
|
// this.handleWsMessage(res.data)
|
||||||
|
// })
|
||||||
|
|
||||||
|
// this.ws.onClose(() => {
|
||||||
|
// console.log("WebSocket已关闭")
|
||||||
|
// })
|
||||||
|
|
||||||
|
// this.ws.onError((err) => {
|
||||||
|
// console.error("WebSocket错误", err)
|
||||||
|
// })
|
||||||
|
},
|
||||||
|
|
||||||
|
handleWsMessage(data) {
|
||||||
|
if (data != 'ping') {
|
||||||
|
try {
|
||||||
|
showNotification(data.title, data.content, data)
|
||||||
|
// const msg = JSON.parse(data)
|
||||||
|
// console.log("收到消息:", msg)
|
||||||
|
// uni.$emit("wsMessage", msg) // 分发消息
|
||||||
|
} catch (e) {
|
||||||
|
console.error("消息解析失败:", data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
closeWebSocket() {
|
||||||
|
if (this.ws) {
|
||||||
|
this.ws.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
2
main.js
2
main.js
@@ -3,7 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
|
import ws from '@/utils/websocket.js'
|
||||||
|
|
||||||
|
Vue.prototype.$ws = ws
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
|
|
||||||
App.mpType = 'app';
|
App.mpType = 'app';
|
||||||
|
@@ -28,8 +28,7 @@
|
|||||||
"modules" : {
|
"modules" : {
|
||||||
"Payment" : {},
|
"Payment" : {},
|
||||||
"Camera" : {},
|
"Camera" : {},
|
||||||
"Barcode" : {},
|
"Barcode" : {}
|
||||||
"Push" : {}
|
|
||||||
},
|
},
|
||||||
"distribute" : {
|
"distribute" : {
|
||||||
"android" : {
|
"android" : {
|
||||||
@@ -54,7 +53,8 @@
|
|||||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
|
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_NOTIFICATION_POLICY\"/>"
|
||||||
],
|
],
|
||||||
"abiFilters" : [ "armeabi-v7a", "arm64-v8a" ]
|
"abiFilters" : [ "armeabi-v7a", "arm64-v8a" ]
|
||||||
},
|
},
|
||||||
@@ -74,18 +74,7 @@
|
|||||||
},
|
},
|
||||||
"appleiap" : {}
|
"appleiap" : {}
|
||||||
},
|
},
|
||||||
"push" : {
|
"push" : {}
|
||||||
"unipush" : {
|
|
||||||
"version" : "2",
|
|
||||||
"offline" : true,
|
|
||||||
"honor" : {},
|
|
||||||
"meizu" : {},
|
|
||||||
"mi" : {},
|
|
||||||
"vivo" : {},
|
|
||||||
"oppo" : {},
|
|
||||||
"hms" : {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"icons" : {
|
"icons" : {
|
||||||
"android" : {
|
"android" : {
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="input-row">
|
<view class="input-row">
|
||||||
<image class="iconfont2" src="/static/ic_login_code.png" />
|
<image class="iconfont2" src="/static/ic_login_code.png" />
|
||||||
<input class="login-input" type="text" placeholder="请输入验证码" v-model="password"/>
|
<input class="login-input" type="text" placeholder="请输入验证码" v-model="password" />
|
||||||
<button class="code-btn">获取校验码</button>
|
<button class="code-btn">获取校验码</button>
|
||||||
</view>
|
</view>
|
||||||
<view class="protocol-row">
|
<view class="protocol-row">
|
||||||
@@ -57,9 +57,9 @@
|
|||||||
activeColor: '#007aff',
|
activeColor: '#007aff',
|
||||||
checked: false
|
checked: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
this.getUserInfo()
|
this.getUserInfo()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async submit() {
|
async submit() {
|
||||||
@@ -85,27 +85,30 @@
|
|||||||
this.$store.commit('$uStore', {
|
this.$store.commit('$uStore', {
|
||||||
name: 'vuex_token',
|
name: 'vuex_token',
|
||||||
value: res.data.access_token
|
value: res.data.access_token
|
||||||
});
|
});
|
||||||
this.getUserInfo()
|
this.getUserInfo()
|
||||||
// setTimeout(() => {
|
// setTimeout(() => {
|
||||||
// uni.reLaunch({
|
// uni.reLaunch({
|
||||||
// url: '/pages/sys/home/home'
|
// url: '/pages/sys/home/home'
|
||||||
// });
|
// });
|
||||||
// }, 500);
|
// }, 500);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getUserInfo(){
|
getUserInfo() {
|
||||||
this.$u.api.getUserInfo({loginCheck: true}).then(res => {
|
this.$u.api.getUserInfo({
|
||||||
if (res.code == '200'){
|
loginCheck: true
|
||||||
this.$store.commit('$uStore', {
|
}).then(res => {
|
||||||
name: 'vuex_user',
|
if (res.code == '200') {
|
||||||
value: res.data.user
|
this.$store.commit('$uStore', {
|
||||||
});
|
name: 'vuex_user',
|
||||||
uni.reLaunch({
|
value: res.data.user
|
||||||
url: '/pages/sys/home/home'
|
});
|
||||||
});
|
uni.$emit("loginSuccess");
|
||||||
}
|
uni.reLaunch({
|
||||||
});
|
url: '/pages/sys/home/home'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleCheckboxChange(e) {
|
handleCheckboxChange(e) {
|
||||||
this.checked = e.target.checked;
|
this.checked = e.target.checked;
|
||||||
|
@@ -31,7 +31,8 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import ws from "@/utils/websocket.js"; // WebSocket 封装类
|
||||||
export default {
|
export default {
|
||||||
name: 'Mine',
|
name: 'Mine',
|
||||||
data() {
|
data() {
|
||||||
@@ -119,6 +120,8 @@
|
|||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/pages/sys/user/myRecord/myRecord'
|
url: '/pages/sys/user/myRecord/myRecord'
|
||||||
});
|
});
|
||||||
|
}else if(idx === 7){
|
||||||
|
ws.send({"data":"{\"bigType\":10,\"createBy\":-1,\"createDept\":103,\"createTime\":\"2025-09-13 16:40:43\",\"description\":\"非法停车\",\"deviceGroupId\":1961274194171736066,\"deviceIp\":\"192.168.24.33\",\"deviceName\":\"2号岗亭监控IP33\",\"id\":1966784089537634305,\"level\":2,\"params\":{},\"reportTime\":\"2025-09-13 16:40:43\",\"servBeginTime\":\"2025-09-13 16:40:43\",\"servEndTime\":\"2025-09-13 18:40:43\",\"smallType\":1028,\"state\":10,\"tenantId\":\"000000\",\"updateTime\":\"2025-09-13 16:40:43\"}","type":"100","title":"预警消息","content":"预警内功"})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
logout() {
|
logout() {
|
||||||
|
15
utils/notify.js
Normal file
15
utils/notify.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
export function showNotification(title, content, extraData = {}) {
|
||||||
|
// App-Plus 平台
|
||||||
|
if (typeof plus !== 'undefined' && plus.push) {
|
||||||
|
plus.push.createMessage(content, extraData, function(result){
|
||||||
|
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// H5 或其他平台,可以用 alert / toast 代替
|
||||||
|
uni.showToast({
|
||||||
|
title: content,
|
||||||
|
icon: 'none',
|
||||||
|
duration: 3000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
115
utils/websocket.js
Normal file
115
utils/websocket.js
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
class WebSocketService {
|
||||||
|
constructor() {
|
||||||
|
this.socketTask = null
|
||||||
|
this.isConnected = false
|
||||||
|
this.heartbeatTimer = null
|
||||||
|
this.reconnectTimer = null
|
||||||
|
this.url = ""
|
||||||
|
this.dispatchHandler = null // 统一分发处理器
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(url) {
|
||||||
|
if (this.isConnected) return
|
||||||
|
this.url = url
|
||||||
|
|
||||||
|
this.socketTask = uni.connectSocket({
|
||||||
|
url: url, // 鉴权
|
||||||
|
success: () => console.log("连接请求已发送")
|
||||||
|
})
|
||||||
|
|
||||||
|
// this.socketTask = uni.connectSocket({ url })
|
||||||
|
console.log('WebSocketService', 'connect called, url:', url)
|
||||||
|
|
||||||
|
// 注意:跨平台统一使用 socketTask 的事件监听
|
||||||
|
if (this.socketTask) {
|
||||||
|
this.socketTask.onOpen(() => {
|
||||||
|
console.log("WebSocket 已连接")
|
||||||
|
this.isConnected = true
|
||||||
|
this.startHeartbeat()
|
||||||
|
})
|
||||||
|
|
||||||
|
this.socketTask.onMessage((res) => {
|
||||||
|
console.log("📩 收到消息:", res.data)
|
||||||
|
let msg
|
||||||
|
try {
|
||||||
|
msg = JSON.parse(res.data)
|
||||||
|
} catch (e) {
|
||||||
|
msg = res.data
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统一分发
|
||||||
|
if (this.dispatchHandler) {
|
||||||
|
this.dispatchHandler(msg)
|
||||||
|
} else {
|
||||||
|
console.warn("未注册 dispatchHandler,消息未处理:", msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.socketTask.onClose(() => {
|
||||||
|
console.log("❌ WebSocket 已关闭")
|
||||||
|
this.isConnected = false
|
||||||
|
this.reconnect()
|
||||||
|
})
|
||||||
|
|
||||||
|
this.socketTask.onError((err) => {
|
||||||
|
console.error("⚠️ WebSocket 错误:", err)
|
||||||
|
this.isConnected = false
|
||||||
|
this.reconnect()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error("WebSocketService: socketTask 获取失败,可能平台不支持")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
send(data) {
|
||||||
|
if (this.isConnected && this.socketTask) {
|
||||||
|
this.socketTask.send({
|
||||||
|
data: typeof data === "string" ? data : JSON.stringify(data),
|
||||||
|
})
|
||||||
|
console.log('WebSocketService', 'send:', data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startHeartbeat() {
|
||||||
|
console.log('WebSocketService', 'startHeartbeat')
|
||||||
|
this.clearHeartbeat()
|
||||||
|
this.heartbeatTimer = setInterval(() => {
|
||||||
|
if (this.isConnected) {
|
||||||
|
this.send("ping")
|
||||||
|
console.log('WebSocketService', 'heartbeat ping sent')
|
||||||
|
}
|
||||||
|
}, 30000)
|
||||||
|
}
|
||||||
|
|
||||||
|
clearHeartbeat() {
|
||||||
|
if (this.heartbeatTimer) {
|
||||||
|
clearInterval(this.heartbeatTimer)
|
||||||
|
this.heartbeatTimer = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reconnect() {
|
||||||
|
if (this.reconnectTimer) return
|
||||||
|
console.log("⏳ 5秒后尝试重连...")
|
||||||
|
this.reconnectTimer = setTimeout(() => {
|
||||||
|
this.connect(this.url)
|
||||||
|
this.reconnectTimer = null
|
||||||
|
}, 5000)
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.clearHeartbeat()
|
||||||
|
if (this.socketTask) {
|
||||||
|
this.socketTask.close()
|
||||||
|
this.socketTask = null
|
||||||
|
}
|
||||||
|
this.isConnected = false
|
||||||
|
console.log('WebSocketService', 'close called')
|
||||||
|
}
|
||||||
|
|
||||||
|
setDispatchHandler(handler) {
|
||||||
|
this.dispatchHandler = handler
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new WebSocketService()
|
Reference in New Issue
Block a user