1
0
forked from dyf/dyf-vue-ui
Files
dyf-vue-ui/src/views/controlCenter/670/index.vue

1088 lines
30 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="device-page p-2">
<!-- 头部信息栏 -->
<div class="header-bar">
<div>设备名称{{ deviceDetail.deviceName }}IMEI:{{ deviceDetail.deviceImei }}</div>
<div>设备型号{{ deviceDetail.typeName }}</div>
<div class="device-status">
设备状态
<span :class="{ online: deviceDetail.onlineStatus === 1, offline: deviceDetail?.onlineStatus === 0 }">
{{ deviceDetail.onlineStatus === 1 ? '在线' : '离线' }}
</span>
</div>
<div>电量{{ deviceDetail.staPowerPercent || 0 }}%</div>
<div>续航{{ powerTime }}</div>
</div>
<!-- 主体内容区域 -->
<div class="content-wrapper">
<el-row :gutter="20" class="content-row" :class="deviceDetail.sta_ShakeBit == 1 || deviceDetail.staSOSGrade == 1 ? '' : 'displayNone'">
<el-col :lg="24" :xs="24">
<div class="staticRwo" :class="deviceDetail.sta_ShakeBit == 1 ? '' : 'displayNone'">设备静止报警中!</div>
<div class="staticRwo" :class="deviceDetail.staSOSGrade == 1 && Status.timeOut > 0 ? '' : 'displayNone'" @click="showClose()">
设备强制报警中<span v-show="Status.timeOut > 0">,{{ Status.timeOut }}S</span>!
</div>
</el-col>
</el-row>
<el-row :gutter="20" class="content-row">
<el-col :lg="8" :xs="24">
<div class="content-card">
<div class="item">
<h4 class="section-title">SOS档位</h4>
<div class="light-mode">
<div
class="mode-card"
:class="{ 'active': Status.sosMode == mode.id }"
@click.stop="handleModeClick(mode.id, 'sosMode')"
v-for="mode in sosModes"
:key="mode.id"
>
<img :src="Status.sosMode == mode.id ? mode.activeIcon : mode.icon" :alt="mode.name" class="mode-icon" />
<div class="mode-name">{{ mode.name }}</div>
<el-switch :active-value="Status.sosMode != mode.id" :inactive-value="Status.sosMode == mode.id" />
</div>
</div>
</div>
</div>
</el-col>
<el-col :lg="8" :xs="24">
<div class="content-card">
<div class="item">
<h4 class="section-title">静电探测档位</h4>
<div class="light-mode">
<div
class="mode-card"
:class="{ 'active': Status.staticPower == mode.id }"
@click.stop="handleModeClick(mode.id, 'staticPower')"
v-for="mode in staticModes"
:key="mode.id"
>
<img :src="Status.staticPower == mode.id ? mode.activeIcon : mode.icon" :alt="mode.name" class="mode-icon" />
<div class="mode-name">{{ mode.name }}</div>
<el-switch :active-value="Status.staticPower != mode.id" :inactive-value="Status.staticPower == mode.id" />
</div>
</div>
</div>
</div>
</el-col>
<el-col :lg="8" :xs="24">
<div class="content-card">
<div class="fleft item">
<h4 class="section-title">灯光模式</h4>
<div class="light-mode">
<div
class="mode-card"
:class="{ 'active': Status.lightMode == mode.id }"
@click.stop="handleModeClick(mode.id, 'lightMode')"
v-for="mode in lightModes"
:key="mode.id"
>
<img :src="Status.lightMode == mode.id ? mode.activeIcon : mode.icon" :alt="mode.name" class="mode-icon" />
<div class="mode-name">{{ mode.name }}</div>
<el-switch :active-value="Status.lightMode != mode.id" :inactive-value="Status.lightMode == mode.id" />
</div>
</div>
</div>
<div class="clear"></div>
</div>
</el-col>
</el-row>
<el-row :gutter="20" class="content-row">
<el-col :lg="8" :xs="24">
<div class="content-card">
<h4 class="section-title">人员信息登记</h4>
<div class="form-grid">
<div class="form-item">
<span class="form-label">单位:</span>
<el-input v-if="deviceDetail" placeholder="请输入单位" v-model="deviceDetail.personnelInfo.unitName" />
</div>
<div class="form-item">
<span class="form-label">职位:</span>
<el-input v-if="deviceDetail" placeholder="请输入职位" v-model="deviceDetail.personnelInfo.position" />
</div>
<div class="form-item">
<span class="form-label">姓名:</span>
<el-input v-if="deviceDetail" placeholder="请输入姓名" v-model="deviceDetail.personnelInfo.name" />
</div>
<div class="form-item">
<span class="form-label">ID:</span>
<el-input v-if="deviceDetail" placeholder="请输入ID" v-model="deviceDetail.personnelInfo.code" />
</div>
<el-button
type="primary"
class="register-btn"
@click="registerPostInit"
:loading="fullscreenLoading"
:loading-text="fullscreenLoading ? '登记中...' : '登记'"
>
{{ fullscreenLoading ? '登记中' : '登记' }}</el-button
>
</div>
</div>
</el-col>
<el-col :lg="8" :xs="24">
<div class="content-card">
<h4 class="section-title">发送信息</h4>
<div class="message-content">
<el-input
type="textarea"
class="textareaTFT"
:rows="4"
:maxlength="16"
:show-word-limit="true"
placeholder="现场危险,停止救援!紧急撤离至安全区域!"
v-model="deviceDetail.sendMsg"
resize="none"
/>
<div style="text-align: end; clear: both">
<el-button
type="primary"
class="send-btn"
@click="sendTextMessage"
:loading="sendTextLoading"
:loading-text="sendTextLoading ? '发送中...' : '发送'"
>
{{ sendTextLoading ? '发送中' : '发送' }}</el-button
>
</div>
</div>
</div>
</el-col>
<el-col :lg="8" :xs="24">
<div class="content-card_gps">
<h4 class="section-title">位置信息</h4>
<div class="location-info">
<div class="location-item">
<span class="location-icon"></span>
<span
>经纬度 {{ deviceDetail && deviceDetail.longitude ? Number(deviceDetail.longitude).toFixed(4) : '无' }}
{{ deviceDetail && deviceDetail.latitude ? Number(deviceDetail.latitude).toFixed(4) : '无' }}
</span>
</div>
<div class="location-item">
<div>
地址 <span class="lacatin_gps">{{ deviceDetail.address || '未获取到地址' }}</span>
</div>
<el-button link type="primary" class="view-btn" @click="lookMap(deviceDetail)">查看</el-button>
</div>
</div>
</div>
</el-col>
</el-row>
</div>
<!-- ===========充电提示框====== -->
<el-dialog title="充电提示" v-model="centerDialogVisible" width="15%" :draggable="true">
<div style="display: flex; align-items: center">
<h3 style="color: rgba(224, 52, 52, 1)">设备电量低于20%</h3>
</div>
<div>请及时充电</div>
<span slot="footer" class="dialog-footer" style="text-align: right; display: block">
<el-button type="primary" @click="centerDialogVisible = false"> </el-button>
</span>
</el-dialog>
<!-- 提示框 -->
<el-dialog :width="300" :draggable="true" v-model="Status.confirm.Visible" :title="Status.confirm.title" width="500" center>
<span>
{{ Status.confirm.text }}
</span>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="Status.confirm.OkCallback">{{ Status.confirm.OkTxt || '确定' }} </el-button>
<el-button v-show="Status.confirm.showCancel" @click="Status.confirm.cancelCallback">{{ Status.confirm.cancelTxt || '取消' }}</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="DeviceControl" lang="ts">
const route = useRoute();
import { useMqtt } from '@/utils/mqtt';
import api from '@/api/controlCenter/controlPanel/670';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const router = useRouter();
// 导入图片资源(确保路径正确)
import strongLightDefault from '@/assets/images/strong-light.png';
import strongLightActive from '@/assets/images/strong-light_HL.png';
import floodLightDefault from '@/assets/images/flood-light.png';
import floodLightActive from '@/assets/images/flood-light_HL.png';
import di from '@/assets/images/di.png';
import diAc from '@/assets/images/diAc.png';
import high from '@/assets/images/high.png';
import highAc from '@/assets/images/highAc.png';
import rb from '@/assets/images/rb.png';
import rbAc from '@/assets/images/rbAc.png';
import sg from '@/assets/images/sg.png';
import sgAc from '@/assets/images/sgAc.png';
import zhong from '@/assets/images/zhong.png';
import zhongAc from '@/assets/images/zhongAc.png';
import closeDefault from '@/assets/images/close.png';
import closeActive from '@/assets/images/close_HL.png';
import { hi } from 'element-plus/es/locale/index.mjs';
const fullscreenLoading = ref(false);
var timer = null;
const sendTextLoading = ref(false);
const centerDialogVisible = ref(false);
const { connected, connect, subscribe, onConnect, onError, onMessage, disconnect } = useMqtt();
const Status = reactive<any>({
sosMode: null,
staticPower: null,
lightMode: null,
confirm: {
//弹出框的配置
Visible: false,
title: '',
text: '',
cancelCallback: null,
OkCallback: null,
showCancel: true,
OkTxt: '',
cancelTxt: ''
},
timeOut: null
});
// 灯光模式数据
const lightModes = ref<any[]>([
{
id: '1',
name: '强光',
icon: strongLightDefault, // 直接使用导入的变量
activeIcon: strongLightActive,
active: false
},
{
id: '2',
name: '弱光',
icon: floodLightDefault,
activeIcon: floodLightActive,
active: false
},
{
id: '0',
name: '关闭',
icon: closeDefault,
activeIcon: closeActive,
active: false
}
]);
//SOS档位
const sosModes = ref<any[]>([
{
id: '1',
name: '声光报警',
icon: sg, // 直接使用导入的变量
activeIcon: sgAc,
active: false
},
{
id: '2',
name: '红蓝模式',
icon: rb, // 直接使用导入的变量
activeIcon: rbAc,
active: false
},
{
id: '0',
name: '关闭',
icon: closeDefault, // 直接使用导入的变量
activeIcon: closeActive,
active: false
}
]);
//静电探测
const staticModes = ref<any[]>([
{
id: '3',
name: '高档',
icon: high, // 直接使用导入的变量
activeIcon: highAc,
active: false
},
{
id: '2',
name: '中档',
icon: zhong, // 直接使用导入的变量
activeIcon: zhongAc,
active: false
},
{
id: '1',
name: '低档',
icon: di, // 直接使用导入的变量
activeIcon: diAc,
active: false
},
{
id: '0',
name: '关闭',
icon: closeDefault, // 直接使用导入的变量
activeIcon: closeActive,
active: false
}
]);
//续航时间显示成人类友好时间
var powerTime = computed(() => {
let lightingTime = deviceDetail.value.staPowerTime;
let hours = Math.floor(lightingTime / 60);
let remainingMinutes = lightingTime % 60;
let xuhang = '';
// 处理不同情况的显示
if (hours === 0) {
xuhang = `${remainingMinutes}分钟`;
} else if (remainingMinutes === 0) {
xuhang = `${hours}小时`;
} else {
xuhang = `${hours}小时${remainingMinutes}分钟`;
}
return xuhang;
});
const deviceDetail = ref<any>({
'deviceId': null,
'deviceName': null,
'deviceImei': null,
'deviceMac': null,
'communicationMode': null,
'devicePic': null,
'typeName': null,
'bluetoothName': null,
'deviceStatus': null,
'personnelInfo': {
'id': null,
'deviceId': null,
'name': null,
'position': null,
'unitName': null,
'code': null
},
'onlineStatus': null,
'longitude': null,
'latitude': null,
'address': null,
'staDetectGrade': null,
'staLightGrade': null,
'staSOSGrade': null,
'staPowerTime': null,
'staPowerPercent': null,
'staDetectResult': null,
'sendMsg': null,
'sta_ShakeBit': null
});
//模式设置
const handleModeClick = async (id: string, type: string) => {
if (Status[type] == id) {
return;
}
let sendCmd = (callback) => {
let json = { 'deviceId': route.params.deviceId, 'deviceImei': deviceDetail.value.deviceImei, 'instructValue': id };
let dic = { promise: null, callback: null, key: '' };
//测试环境假装成功
dic.promise = Promise.resolve({ code: 200, msg: '操作成功' });
let arr = [];
if (type == 'lightMode') {
dic.promise = api.lightModeSettings(json);
arr = lightModes.value;
} else if (type == 'staticPower') {
dic.promise = api.staticPowerSetting(json);
arr = staticModes.value;
} else if (type == 'sosMode') {
dic.promise = api.SosSetting(json);
arr = sosModes.value;
}
dic.callback = () => {
arr.find((v) => {
if (v.id == id) {
v.active = true;
} else {
v.active = false;
}
});
};
dic.promise.then((res) => {
if (res.code === 200) {
Status[type] = id;
ElMessage.closeAll();
proxy?.$modal.msgSuccess(res.msg);
if (dic.callback) {
dic.callback();
}
if (callback) {
callback();
}
} else {
proxy?.$modal.msgError(res.msg);
}
});
};
if (type == 'sosMode' && Status.sosMode === '1' && id === '0' && timer) {
showClose();
return;
} else if (type == 'sosMode' && id === '1' && timer == null) {
ShowConfirm({
title: '提示',
text: '您确认开启180秒强制报警',
cancelCallback: () => {
timer = null;
},
OkCallback: () => {
sendCmd(function () {
Status.confirm.Visible = false;
deviceDetail.value.staSOSGrade = '1';
Status.timeOut = 180;
timer = setInterval(() => {
if (Status.timeOut === 0) {
clearInterval(timer);
timer = null;
hideConfirm();
handleModeClick('1', 'sosMode');
deviceDetail.value.staSOSGrade = '0';
return;
}
Status.timeOut = Status.timeOut - 1;
Status.confirm.text = '设备强制报警中:' + Status.timeOut;
}, 1000);
});
},
showCancel: true,
OkTxt: '开启',
cancelTxt: '取消'
});
} else {
sendCmd(null);
}
};
const getList = () => {
return new Promise((resolve, reject) => {
api
.deviceRealTimeStatus(route.params.deviceId)
.then((res) => {
if (res && res.code == 200) {
let keys = Object.keys(res.data);
keys.forEach((key) => {
deviceDetail.value[key] = res.data[key];
});
Status.sosMode = res.data.staSOSGrade;
Status.staticPower = res.data.staDetectGrade;
Status.lightMode = res.data.staLightGrade;
if (!deviceDetail.value.personnelInfo) {
deviceDetail.value.personnelInfo = {
'id': null,
'deviceId': null,
'name': null,
'position': null,
'unitName': null,
'code': null
};
}
}
})
.finally(resolve);
});
};
// 人员信息发送
const registerPostInit = () => {
if (!deviceDetail.value.personnelInfo.unitName) {
ElMessage.closeAll();
proxy?.$modal.msgWarning('单位名称不能为空');
return;
}
if (!deviceDetail.value.personnelInfo.name) {
ElMessage.closeAll();
proxy?.$modal.msgWarning('姓名不能为空');
return;
}
if (!deviceDetail.value.personnelInfo.position) {
ElMessage.closeAll();
proxy?.$modal.msgWarning('职位不能为空');
return;
}
if (!deviceDetail.value.personnelInfo.code) {
ElMessage.closeAll();
proxy?.$modal.msgWarning('ID不能为空');
return;
}
let data = {
code: deviceDetail.value.personnelInfo.code,
name: deviceDetail.value.personnelInfo.name,
position: deviceDetail.value.personnelInfo.position,
unitName: deviceDetail.value.personnelInfo.unitName,
deviceId: route.params.deviceId,
deviceImei: deviceDetail.value.deviceImei
};
fullscreenLoading.value = true;
api.SendUser(data).then((res) => {
console.log(res, 'res');
if (res.code === 200) {
fullscreenLoading.value = false;
proxy?.$modal.msgSuccess(res.msg);
} else {
fullscreenLoading.value = false;
proxy?.$modal.msgError(res.msg);
}
});
};
// 发送文本消息
const sendTextMessage = async () => {
if (!deviceDetail.value.sendMsg) {
ElMessage.closeAll();
proxy?.$modal.msgWarning('发送信息不能为空');
return;
} else if (deviceDetail.value.sendMsg.length < 2) {
ElMessage.closeAll();
proxy?.$modal.msgWarning('发送信息字数太少,至少2字,最多18字');
return;
}
let json = {
sendMsg: deviceDetail.value.sendMsg,
deviceIds: [route.params.deviceId],
deviceImeiList: [deviceDetail.value.deviceImei],
instructValue: '',
batchId: ''
};
api.SendMessage(json).then((res) => {
if (res.code === 200) {
ElMessage.closeAll();
proxy?.$modal.msgSuccess(res.msg);
} else {
proxy?.$modal.msgError(res.msg);
}
});
};
const lookMap = (row: any) => {
console.log(row, 'row');
router.push({
path: '/controlCenter/controlPanel', // 目标页面的正确路由路径(需与项目路由配置一致)
query: {
view: 'map',
deviceId: row.deviceId // 可选传递当前设备ID用于地图定位/筛选
}
});
};
function showClose() {
Status.confirm.Visible = true;
Status.confirm.OkTxt = '关闭';
Status.confirm.OkCallback = () => {
clearInterval(timer);
timer = null;
handleModeClick('0', 'sosMode');
deviceDetail.value.staSOSGrade = '0';
Status.timeOut = 0;
hideConfirm();
};
}
// 处理设备消息
const handleDeviceMessage = (payload: any) => {
let json = null;
try {
json = JSON.parse(payload);
} catch (ex) {
return;
}
let keys = Object.keys(json);
function parseDataMQ(json) {
try {
debugger;
deviceDetail.value.staDetectGrade = json.sta_DetectGrade;
deviceDetail.value.staLightGrade = json.sta_LightGrade;
deviceDetail.value.staDetectResult = json.sta_DetectResult;
deviceDetail.value.staSOSGrade = json.sta_SOSGrade;
deviceDetail.value.sta_ShakeBit = json.sta_ShakeBit;
deviceDetail.value.staPowerTime = json.sta_PowerTime;
deviceDetail.value.staPowerPercent = json.sta_PowerPercent;
deviceDetail.value.longitude = json.sta_longitude;
deviceDetail.value.latitude = json.sta_latitude;
deviceDetail.value.onlineStatus = 1;
Status.sosMode = json.sta_SOSGrade;
Status.staticPower = json.sta_DetectGrade;
Status.lightMode = json.sta_LightGrade;
console.log('Status=', Status);
console.log('sosModes=', sosModes.value);
console.log('sta_SOSGrade=', json.sta_SOSGrade);
if (json.sta_PowerPercent < 20) {
centerDialogVisible.value = true;
}
if (json.sta_SOSGrade == 1 && json.sta_ShakeBit == 1) {
confirm('设备SOS报警、静止预警中');
return;
}
if (json.sta_SOSGrade == 1) {
confirm('设备SOS报警中');
}
if (json.sta_ShakeBit == 1) {
confirm('设备静止报警中');
}
} catch (err) {}
}
if (keys.indexOf('sta_DetectGrade') > -1) {
//上报的报文
console.log('收到设备上报的数据', payload);
parseDataMQ(json);
}
};
onMounted(async () => {
await getList(); // 先获取设备信息
// 连接mqtt
onConnect(async () => {
const deviceImei = deviceDetail.value.deviceImei;
if (!deviceImei) {
return;
}
try {
await subscribe(`A/${deviceImei}`, { qos: 1 });
console.log('订阅成功');
} catch (err) {
console.error('订阅失败onConnect内:', err);
}
});
// 2. 注册消息接收回调(核心:处理设备发送的消息)
onMessage((msg) => {
console.log('收到新消息:', {
主题: msg.topic,
内容: msg.payload,
时间: msg.time,
QoS: msg.qos
});
// 在这里处理消息(根据实际业务逻辑)
handleDeviceMessage(msg.payload);
});
onError((err) => {
console.error('MQTT连接失败原因:', err.message); // 关键:打印连接失败的具体原因
});
connect();
});
onUnmounted(() => {
// 只有当连接已建立时,才执行断开操作(避免无效调用)
if (connected.value) {
console.log('页面离开断开MQTT连接');
disconnect(); // 调用断开连接方法
}
});
window.confirm = function (text, OK, cancel, title) {
let Cfg = {
Visible: true,
title: title ? title : '提示',
text: text ? text : '此操作不可逆,您确定这样做吗?',
OkCallback: () => {
Status.confirm.Visible = false;
if (OK) {
OK();
}
},
showCancel: true,
cancelCallback: () => {
Status.confirm.Visible = false;
if (cancel) {
cancel();
}
},
OkTxt: '',
cancelTxt: ''
};
Status.confirm = Cfg;
};
window.ShowConfirm = function (option: any) {
let Cfg = {
Visible: true,
title: option.title ? option.title : '提示',
text: option.text ? option.text : '此操作不可逆,您确定这样做吗?',
OkCallback: () => {
Status.confirm.Visible = false;
if (option.OkCallback) {
option.OkCallback();
}
},
showCancel: true,
cancelCallback: () => {
Status.confirm.Visible = false;
if (option.cancelCallback) {
option.cancelCallback();
}
},
OkTxt: '',
cancelTxt: ''
};
Status.confirm = Cfg;
};
window.hideConfirm = function () {
let Cfg = {
Visible: false,
title: '提示',
text: '',
cancelCallback: null,
OkCallback: null,
showCancel: false,
OkTxt: '',
cancelTxt: ''
};
Status.confirm = Cfg;
};
</script>
<style lang="scss" scoped>
.p-2 {
background: rgba(247, 248, 252, 1);
min-height: 100vh;
box-sizing: border-box;
padding: 15px;
}
.device-page {
.header-bar {
border-radius: 8px;
background: linear-gradient(135deg, #3400e7, #009bff);
color: white;
padding: 20px;
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 600;
.device-status {
.online {
color: #00ff00;
}
.offline {
color: rgb(224, 52, 52);
}
}
}
.content-wrapper {
.content-row {
margin-bottom: 10px;
}
.content-card {
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 34, 96, 0.1);
background: white;
padding: 0px 20px 50px;
border: 1px solid #ebeef5;
height: 289px;
position: relative;
}
.content-card_gps {
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 34, 96, 0.1);
background: white;
padding: 0px 20px 50px;
border: 1px solid #ebeef5;
height: 100%;
}
.section-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 20px;
color: #303133;
}
.light-mode {
display: flex;
justify-content: space-between;
}
.lacatin_gps {
height: 70px;
border-radius: 4px;
background: rgba(247, 248, 252, 1);
display: inline-block;
width: 400px;
padding: 10px;
}
.mode-card {
display: flex;
flex-direction: column;
align-items: center;
padding: 15px;
border: 1px solid #dcdfe6;
border-radius: 8px;
width: calc(calc(100% - 30px) / 4);
cursor: pointer;
transition: all 0.3s ease;
&.active {
border-color: #409eff;
background-color: rgba(64, 158, 255, 0.05);
}
.mode-icon {
width: 48px;
margin-bottom: 10px;
transition: all 0.3s ease;
object-fit: scale-down;
height: 50px;
}
.mode-name {
font-size: 14px;
margin-bottom: 12px;
color: #606266;
}
.el-switch {
--el-switch-on-color: #409eff;
--el-switch-off-color: #dcdfe6;
}
}
.brightness-alarm {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
.brightness-control {
display: flex;
align-items: center;
gap: 10px;
border-radius: 39px;
box-shadow: 0px 0px 6px 0px rgba(0, 34, 96, 0.1);
background: rgba(255, 255, 255, 1);
width: 70%;
height: 54px;
padding: 10px 20px;
.brightness-label {
font-size: 14px;
color: #606266;
min-width: 70px;
}
.brightness-value {
font-size: 14px;
color: #409eff;
font-weight: 500;
}
.save-btn {
padding: 6px 20px;
border-radius: 29px;
background: rgba(2, 124, 251, 1);
border: none;
}
.inputTFT {
width: 130px;
height: 40px;
}
}
.alarm-btn {
background-color: rgba(224, 52, 52, 1);
border-color: rgba(224, 52, 52, 1);
padding: 8px 20px;
border-radius: 27px;
}
}
.location-info {
.location-item {
display: flex;
align-items: center;
margin-bottom: 15px;
font-size: 14px;
color: #606266;
.location-icon {
margin-right: 8px;
font-weight: bold;
color: #409eff;
}
.view-btn {
margin: 0 8px;
padding: 0;
font-size: 13px;
}
}
}
.form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
margin-bottom: 15px;
text-align: right;
.form-item {
display: flex;
align-items: center;
.form-label {
min-width: 35px;
font-size: 14px;
color: #606266;
margin-right: 10px;
}
.el-input {
flex: 1;
}
}
.register-btn {
grid-column: 1 / 3;
justify-self: start;
padding: 6px 20px;
position: absolute;
right: 19px;
bottom: 30px;
border-radius: 29px;
background: rgba(2, 124, 251, 1);
border: none;
}
}
.message-content {
// display: flex;
// flex-direction: column;
// gap: 10px;
.el-textarea {
border: 1px solid rgba(29, 111, 255, 1);
border-radius: 4px;
background: rgba(247, 248, 252, 1);
border-radius: 6px;
padding: 10px;
}
.el-textarea__inner {
background: rgba(247, 248, 252, 1);
}
.send-btn {
align-self: flex-end;
padding: 10px 20px;
border-radius: 29px;
background: rgba(2, 124, 251, 1);
border: none;
margin: 20px 0px 30px 0;
}
}
.upload-area {
display: flex;
justify-content: center;
align-items: center;
height: 100px;
border: 1px dashed #dcdfe6;
border-radius: 6px;
cursor: pointer;
}
.video-input {
display: flex;
gap: 10px;
align-items: center;
.el-input {
flex: 1;
}
.save-video-btn {
padding: 6px 12px;
}
}
}
// 响应式调整
@media (max-width: 768px) {
.header-bar {
flex-direction: column;
align-items: flex-start;
gap: 16px;
}
.form-grid {
grid-template-columns: 1fr;
}
.form-grid .register-btn {
grid-column: 1;
}
.light-mode .mode-group {
gap: 10px;
}
.light-mode .mode-item {
width: 60px;
}
.light-mode .mode-icon {
width: 30px;
height: 30px;
}
}
}
.path-img {
width: 52px;
height: 28px;
}
.staticRwo {
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 34, 96, 0.1);
background: white;
border: 1px solid #ebeef5;
height: auto;
line-height: 36px;
box-sizing: border-box;
text-indent: 15px;
color: #ff0000;
font-weight: bold;
font-size: 17px;
margin-bottom: 5px;
}
.displayNone {
display: none !important;
}
</style>