mqtt
parent
e7f9d0affa
commit
7372ec452e
|
|
@ -1,220 +1,533 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<uni-section :title="lastTopic" type="line" padding>
|
<!-- 连接配置区域 -->
|
||||||
<uni-grid :column="4" border-color="#03a9f4">
|
<view class="config-section">
|
||||||
<uni-grid-item :index="0">
|
<view class="section-title">MQTT连接配置</view>
|
||||||
<view class="grid-item-box">
|
<form @submit="handleConnect">
|
||||||
<text class="text">{{ data.temp1 }} </text>
|
<view class="form-item">
|
||||||
<text class="text"> 温度1 ℃</text>
|
<label>服务器地址:</label>
|
||||||
|
<input
|
||||||
|
v-model="mqttConfig.broker"
|
||||||
|
type="text"
|
||||||
|
placeholder="如:ws://test.mosquitto.org:8080/mqtt"
|
||||||
|
class="form-input"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</uni-grid-item>
|
<view class="form-item" v-if="false">
|
||||||
<uni-grid-item :index="1">
|
<label>客户端ID:</label>
|
||||||
<view class="grid-item-box">
|
<input
|
||||||
<text class="text">{{ data.temp2 }}</text>
|
v-model="mqttConfig.clientId"
|
||||||
<text class="text"> 温度2 </text>
|
type="text"
|
||||||
|
placeholder="自动生成或自定义"
|
||||||
|
class="form-input"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</uni-grid-item>
|
<view class="form-item">
|
||||||
<uni-grid-item :index="2">
|
<label>用户名:</label>
|
||||||
<view class="grid-item-box">
|
<input
|
||||||
<text class="text">{{ data.temp3 }}</text>
|
v-model="mqttConfig.username"
|
||||||
<text class="text"> 温度3 </text>
|
type="text"
|
||||||
|
placeholder="可选"
|
||||||
|
class="form-input"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</uni-grid-item>
|
<view class="form-item">
|
||||||
<uni-grid-item :index="3">
|
<label>密码:</label>
|
||||||
<view class="grid-item-box">
|
<input
|
||||||
<text class="text">{{ data.temp4 }}</text>
|
v-model="mqttConfig.password"
|
||||||
<text class="text"> 温度4 </text>
|
type="password"
|
||||||
|
placeholder="可选"
|
||||||
|
class="form-input"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</uni-grid-item>
|
<view class="form-item" v-if="false">
|
||||||
</uni-grid>
|
<label>连接超时:</label>
|
||||||
<uni-grid :column="4" border-color="#03a9f4">
|
<input
|
||||||
<uni-grid-item :index="0">
|
v-model.number="mqttConfig.timeout"
|
||||||
<view class="grid-item-box">
|
type="number"
|
||||||
<text class="text">{{ data.humi1 }}</text>
|
placeholder="默认30秒"
|
||||||
<text class="text"> 湿度1 </text>
|
class="form-input"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</uni-grid-item>
|
|
||||||
<uni-grid-item :index="1">
|
<view class="btn-group">
|
||||||
<view class="grid-item-box">
|
<button
|
||||||
<text class="text">{{ data.humi2 }}</text>
|
type="primary"
|
||||||
<text class="text"> 湿度2 </text>
|
:disabled="isConnected"
|
||||||
|
@click="handleConnect"
|
||||||
|
>
|
||||||
|
连接
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="warn"
|
||||||
|
:disabled="!isConnected"
|
||||||
|
@click="handleDisconnect"
|
||||||
|
>
|
||||||
|
断开连接
|
||||||
|
</button>
|
||||||
</view>
|
</view>
|
||||||
</uni-grid-item>
|
</form>
|
||||||
<uni-grid-item :index="2">
|
|
||||||
<view class="grid-item-box">
|
|
||||||
<text class="text">{{ data.humi3 }}</text>
|
|
||||||
<text class="text"> 湿度3 </text>
|
|
||||||
</view>
|
</view>
|
||||||
</uni-grid-item>
|
|
||||||
<uni-grid-item :index="3">
|
<!-- 订阅区域 -->
|
||||||
<view class="grid-item-box">
|
<view class="subscribe-section" v-if="isConnected">
|
||||||
<text class="text">{{ data.humi4 }}</text>
|
<view class="section-title">主题订阅</view>
|
||||||
<text class="text"> 湿度4 %RH</text>
|
<view class="form-item">
|
||||||
|
<label>订阅主题:</label>
|
||||||
|
<input
|
||||||
|
v-model="subscribeTopic"
|
||||||
|
type="text"
|
||||||
|
placeholder="如:test/topic"
|
||||||
|
class="form-input"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</uni-grid-item>
|
<button
|
||||||
</uni-grid>
|
type="primary"
|
||||||
</uni-section>
|
@click="handleSubscribe"
|
||||||
|
>
|
||||||
|
订阅
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- 已订阅主题列表 -->
|
||||||
|
<view class="topic-list" v-if="subscribedTopics.length">
|
||||||
|
<view class="list-title">已订阅主题:</view>
|
||||||
|
<view
|
||||||
|
class="topic-item"
|
||||||
|
v-for="(topic, index) in subscribedTopics"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
{{topic}}
|
||||||
|
<button
|
||||||
|
size="mini"
|
||||||
|
type="warn"
|
||||||
|
@click="handleUnsubscribe(topic)"
|
||||||
|
>
|
||||||
|
取消订阅
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 消息日志区域 -->
|
||||||
|
<view class="log-section">
|
||||||
|
<view class="section-title">消息日志</view>
|
||||||
|
<scroll-view
|
||||||
|
class="log-content"
|
||||||
|
scroll-y="true"
|
||||||
|
:style="{height: logHeight + 'px'}"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="log-item"
|
||||||
|
v-for="(log, index) in messageLogs"
|
||||||
|
:key="index"
|
||||||
|
:class="{'received': log.type === 'received', 'sent': log.type === 'sent', 'system': log.type === 'system'}"
|
||||||
|
>
|
||||||
|
<view class="log-time">{{log.time}}</view>
|
||||||
|
<view class="log-type">{{log.type === 'received' ? '接收' : log.type === 'sent' ? '发送' : '系统'}}</view>
|
||||||
|
<view class="log-topic">主题:{{log.topic}}</view>
|
||||||
|
<view class="log-message">内容:{{log.message}}</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 发布消息区域 -->
|
||||||
|
<view class="publish-section" v-if="isConnected">
|
||||||
|
<view class="section-title">发布消息</view>
|
||||||
|
<view class="form-item">
|
||||||
|
<label>发布主题:</label>
|
||||||
|
<input
|
||||||
|
v-model="publishTopic"
|
||||||
|
type="text"
|
||||||
|
placeholder="如:test/topic"
|
||||||
|
class="form-input"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="form-item">
|
||||||
|
<label>消息内容:</label>
|
||||||
|
<textarea
|
||||||
|
v-model="publishMessage"
|
||||||
|
placeholder="输入要发布的消息内容"
|
||||||
|
class="form-textarea"
|
||||||
|
></textarea>
|
||||||
|
</view>
|
||||||
|
<button
|
||||||
|
type="primary"
|
||||||
|
@click="handlePublish"
|
||||||
|
>
|
||||||
|
发布消息
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import mqtt from 'mqtt/dist/mqtt.js' //引入mqtt依赖
|
import mqtt from 'mqtt/dist/mqtt.min'
|
||||||
// 然后 mqtt.connect(...)
|
|
||||||
|
|
||||||
let client = null
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
connected: false,
|
// MQTT配置
|
||||||
data: {
|
mqttConfig: {
|
||||||
temp1: null,
|
broker: 'ws://1.94.254.176:9001/mqtt', // 公共测试服务器
|
||||||
humi1: null,
|
clientId: 'uniapp_mqtt_' + Math.random().toString(16).substr(2, 8),
|
||||||
temp2: null,
|
username: 'admin',
|
||||||
humi2: null,
|
password: 'Admin#12345678',
|
||||||
temp3: null,
|
timeout: 30
|
||||||
humi3: null,
|
|
||||||
temp4: null,
|
|
||||||
humi4: null,
|
|
||||||
},
|
},
|
||||||
lastTopic: "设备" + '',
|
// 连接状态
|
||||||
lastRaw: ''
|
isConnected: false,
|
||||||
|
client: null,
|
||||||
|
// 订阅相关
|
||||||
|
subscribeTopic: '',
|
||||||
|
subscribedTopics: [],
|
||||||
|
// 发布相关
|
||||||
|
publishTopic: '',
|
||||||
|
publishMessage: '',
|
||||||
|
// 消息日志
|
||||||
|
messageLogs: [],
|
||||||
|
logHeight: 300 // 日志区域高度
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onShow() {
|
onReady() {
|
||||||
const clientId = 'uniapp_' + Date.now() + '_' + Math.floor(Math.random() * 100000)
|
// 计算日志区域高度
|
||||||
|
uni.getSystemInfo({
|
||||||
client = mqtt.connect('ws://1.94.254.176:9001', {
|
success: (res) => {
|
||||||
clientId,
|
this.logHeight = res.windowHeight - 600
|
||||||
username: 'admin', // 没有就删
|
|
||||||
password: 'Admin#12345678', // 没有就删
|
|
||||||
clean: true,
|
|
||||||
reconnectPeriod: 2000,
|
|
||||||
connectTimeout: 5000
|
|
||||||
})
|
|
||||||
|
|
||||||
client.on('connect', () => {
|
|
||||||
this.connected = true
|
|
||||||
client.subscribe('dtu/+/up', { qos: 0 })
|
|
||||||
})
|
|
||||||
|
|
||||||
client.on('message', (topic, payload) => {
|
|
||||||
const s = payload.toString()
|
|
||||||
this.lastRaw = s
|
|
||||||
|
|
||||||
// 只处理JSON(混二进制就直接丢)
|
|
||||||
if (!(s.startsWith('{') && s.endsWith('}'))) return
|
|
||||||
let obj
|
|
||||||
try {
|
|
||||||
obj = JSON.parse(s)
|
|
||||||
const allKeysNumeric = Object.keys(obj).every(key => /^\d+$/.test(key));
|
|
||||||
if (Object.keys(obj).length <= 0 || !allKeysNumeric) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch(e) { return }
|
|
||||||
|
|
||||||
// 你的键:温度101~104、湿度201~204(按你之前约定温度/10、湿度/10)
|
|
||||||
const div10 = (v) => (v == null ? null : Math.round((Number(v)/10)*10)/10)
|
|
||||||
this.lastTopic = "设备【" + topic+"】"
|
|
||||||
this.data = {
|
|
||||||
temp1: div10(obj["201"]),
|
|
||||||
humi1: div10(obj["101"]),
|
|
||||||
temp2: div10(obj["202"]),
|
|
||||||
humi2: div10(obj["102"]),
|
|
||||||
temp3: div10(obj["203"]),
|
|
||||||
humi3: div10(obj["103"]),
|
|
||||||
temp4: div10(obj["204"]),
|
|
||||||
humi4: div10(obj["104"])
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on('close', () => { this.connected = false })
|
|
||||||
client.on('error', () => { this.connected = false })
|
|
||||||
},
|
},
|
||||||
onUnload() {
|
onUnload() {
|
||||||
try { client && client.end(true) } catch(e) {}
|
// 页面卸载时断开连接
|
||||||
|
if (this.client && this.isConnected) {
|
||||||
|
this.client.end()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 添加日志
|
||||||
|
addLog(type, topic, message) {
|
||||||
|
const time = new Date().toLocaleTimeString()
|
||||||
|
this.messageLogs.unshift({
|
||||||
|
time,
|
||||||
|
type, // received/sent/system
|
||||||
|
topic,
|
||||||
|
message
|
||||||
|
})
|
||||||
|
// 限制日志数量
|
||||||
|
if (this.messageLogs.length > 100) {
|
||||||
|
this.messageLogs.pop()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// 页面上直接展示:
|
// 连接MQTT服务器
|
||||||
//
|
handleConnect() {
|
||||||
// 连接状态 connected
|
if (!this.mqttConfig.broker) {
|
||||||
//
|
uni.showToast({
|
||||||
// temp1/humi1 … temp4/humi4
|
title: '请输入服务器地址',
|
||||||
//
|
icon: 'none'
|
||||||
// lastTopic 和 lastRaw(排查时非常有用)
|
})
|
||||||
},
|
return
|
||||||
onHide() {
|
|
||||||
client && client.end(true)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 配置连接选项
|
||||||
|
const options = {
|
||||||
|
clientId: this.mqttConfig.clientId || 'uniapp_mqtt_' + Math.random().toString(16).substr(2, 8),
|
||||||
|
username: this.mqttConfig.username,
|
||||||
|
password: this.mqttConfig.password,
|
||||||
|
connectTimeout: (this.mqttConfig.timeout || 30) * 1000,
|
||||||
|
keepalive: 60,
|
||||||
|
clean: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建客户端并连接
|
||||||
|
this.client = mqtt.connect(this.mqttConfig.broker, options)
|
||||||
|
|
||||||
|
// 连接成功回调
|
||||||
|
this.client.on('connect', () => {
|
||||||
|
this.isConnected = true
|
||||||
|
this.addLog('system', '', 'MQTT连接成功')
|
||||||
|
uni.showToast({
|
||||||
|
title: '连接成功',
|
||||||
|
icon: 'success'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 接收消息回调
|
||||||
|
this.client.on('message', (topic, message) => {
|
||||||
|
this.addLog('received', topic, message.toString())
|
||||||
|
})
|
||||||
|
|
||||||
|
// 连接断开回调
|
||||||
|
this.client.on('close', () => {
|
||||||
|
this.isConnected = false
|
||||||
|
this.subscribedTopics = []
|
||||||
|
this.addLog('system', '', 'MQTT连接已断开')
|
||||||
|
})
|
||||||
|
|
||||||
|
// 错误回调
|
||||||
|
this.client.on('error', (error) => {
|
||||||
|
this.isConnected = false
|
||||||
|
this.addLog('system', '', '连接错误:' + error.message)
|
||||||
|
uni.showToast({
|
||||||
|
title: '连接失败:' + error.message,
|
||||||
|
icon: 'none',
|
||||||
|
duration: 3000
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
this.addLog('system', '', '连接异常:' + error.message)
|
||||||
|
uni.showToast({
|
||||||
|
title: '连接异常:' + error.message,
|
||||||
|
icon: 'none',
|
||||||
|
duration: 3000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 断开连接
|
||||||
|
handleDisconnect() {
|
||||||
|
if (this.client) {
|
||||||
|
this.client.end()
|
||||||
|
this.isConnected = false
|
||||||
|
this.subscribedTopics = []
|
||||||
|
this.addLog('system', '', '已手动断开MQTT连接')
|
||||||
|
uni.showToast({
|
||||||
|
title: '已断开连接',
|
||||||
|
icon: 'success'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 订阅主题
|
||||||
|
handleSubscribe() {
|
||||||
|
if (!this.subscribeTopic) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请输入订阅主题',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.subscribedTopics.includes(this.subscribeTopic)) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '该主题已订阅',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client.subscribe(this.subscribeTopic, (error) => {
|
||||||
|
if (error) {
|
||||||
|
this.addLog('system', '', '订阅失败:' + error.message)
|
||||||
|
uni.showToast({
|
||||||
|
title: '订阅失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.subscribedTopics.push(this.subscribeTopic)
|
||||||
|
this.addLog('system', this.subscribeTopic, '订阅成功')
|
||||||
|
uni.showToast({
|
||||||
|
title: '订阅成功',
|
||||||
|
icon: 'success'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 取消订阅
|
||||||
|
handleUnsubscribe(topic) {
|
||||||
|
this.client.unsubscribe(topic, (error) => {
|
||||||
|
if (error) {
|
||||||
|
this.addLog('system', topic, '取消订阅失败:' + error.message)
|
||||||
|
uni.showToast({
|
||||||
|
title: '取消订阅失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.subscribedTopics = this.subscribedTopics.filter(item => item !== topic)
|
||||||
|
this.addLog('system', topic, '取消订阅成功')
|
||||||
|
uni.showToast({
|
||||||
|
title: '取消订阅成功',
|
||||||
|
icon: 'success'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 发布消息
|
||||||
|
handlePublish() {
|
||||||
|
if (!this.publishTopic) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请输入发布主题',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.publishMessage) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请输入消息内容',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client.publish(this.publishTopic, this.publishMessage, (error) => {
|
||||||
|
if (error) {
|
||||||
|
this.addLog('system', this.publishTopic, '发布失败:' + error.message)
|
||||||
|
uni.showToast({
|
||||||
|
title: '发布失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.addLog('sent', this.publishTopic, this.publishMessage)
|
||||||
|
uni.showToast({
|
||||||
|
title: '发布成功',
|
||||||
|
icon: 'success'
|
||||||
|
})
|
||||||
|
// 清空消息输入框
|
||||||
|
this.publishMessage = ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.container {
|
.container {
|
||||||
padding: 20rpx;
|
padding: 15px;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text {
|
.config-section, .subscribe-section, .publish-section, .log-section {
|
||||||
font-size: 22px;
|
background-color: #fff;
|
||||||
font-weight: bolder;
|
border-radius: 8px;
|
||||||
display: inline-block;
|
padding: 15px;
|
||||||
}
|
|
||||||
.text:nth-child(even) {
|
|
||||||
font-size: 14px;
|
|
||||||
margin-top: 5px;
|
|
||||||
color: #9c9c9c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.example-body {
|
|
||||||
/* #ifndef APP-NVUE */
|
|
||||||
// display: block;
|
|
||||||
/* #endif */
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-dynamic-box {
|
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-item-box {
|
.section-title {
|
||||||
flex: 1;
|
font-size: 16px;
|
||||||
// position: relative;
|
font-weight: bold;
|
||||||
/* #ifndef APP-NVUE */
|
margin-bottom: 15px;
|
||||||
|
color: #333;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
/* #endif */
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
margin-bottom: 12px;
|
||||||
justify-content: center;
|
|
||||||
padding: 15px 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-item-box-row {
|
.form-item label {
|
||||||
flex: 1;
|
font-size: 14px;
|
||||||
// position: relative;
|
color: #666;
|
||||||
/* #ifndef APP-NVUE */
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input {
|
||||||
|
height: 40px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-textarea {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
min-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
/* #endif */
|
gap: 10px;
|
||||||
flex-direction: row;
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group button {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topic-list {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-title {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topic-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
padding: 8px 10px;
|
||||||
padding: 15px 0;
|
background-color: #f9f9f9;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.log-section {
|
||||||
/* #ifdef H5 */
|
margin-top: 15px;
|
||||||
@media screen and (min-width: 768px) and (max-width: 1425px) {
|
|
||||||
.swiper {
|
|
||||||
height: 630px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 1425px) {
|
.log-content {
|
||||||
.swiper {
|
background-color: #f9f9f9;
|
||||||
height: 830px;
|
border-radius: 4px;
|
||||||
}
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* #endif */
|
.log-item {
|
||||||
|
padding: 8px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-item.received {
|
||||||
|
background-color: #e8f5e9;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-item.sent {
|
||||||
|
background-color: #e3f2fd;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-item.system {
|
||||||
|
background-color: #fff8e1;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-time {
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-type {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-topic {
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-message {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Loading…
Reference in New Issue