修改反馈问题
This commit is contained in:
parent
239a2401f9
commit
a7cc0e19c9
@ -114,3 +114,7 @@ export async function saveSystemConfig(payload: SystemConfigPayload): Promise<Ap
|
||||
const response = await http.post<ApiResponse<{ send_status: string }>>('/config/system', payload)
|
||||
return response.data
|
||||
}
|
||||
export async function saveDevicePassword(payload: { password: string }): Promise<ApiResponse<{ send_status: string }>> {
|
||||
const response = await http.post<ApiResponse<{ send_status: string }>>('/config/device/password', payload)
|
||||
return response.data
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{ store: any; actions: any }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="panel">
|
||||
<div class="section-header">
|
||||
<h2>报警历史</h2>
|
||||
<div class="actions">
|
||||
<button class="primary" :disabled="store.alarmLoading" @click="actions.refreshAlarms()">
|
||||
{{ store.alarmLoading ? '刷新中...' : '刷新列表' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead><tr><th>类型</th><th>时间</th><th>编号</th><th>内容</th><th>级别</th></tr></thead>
|
||||
<tbody>
|
||||
<tr v-for="alarm in store.alarms" :key="`${alarm.time}-${alarm.no}-${alarm.content}`">
|
||||
<td>{{ alarm.alarm_type }}</td>
|
||||
<td>{{ alarm.time }}</td>
|
||||
<td>{{ alarm.no }}</td>
|
||||
<td>{{ alarm.content }}</td>
|
||||
<td>{{ alarm.level }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="actions">
|
||||
<button class="primary" :disabled="store.alarmLoading || store.alarmPage <= 1" @click="actions.prevAlarmPage()">上一页</button>
|
||||
<button class="primary" :disabled="store.alarmLoading || !store.alarmHasNext" @click="actions.nextAlarmPage()">下一页</button>
|
||||
</div>
|
||||
<p class="hint">当前页:{{ store.alarmPage }},最后刷新:{{ store.alarmUpdatedAt || '--' }}</p>
|
||||
</section>
|
||||
</template>
|
||||
@ -1,107 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { fetchAiAlarmSetting, fetchLineAlarmSetting, saveAiAlarmSetting, saveLineAlarmSetting } from '../api/platform'
|
||||
import type { AiAlarmSettingItem, LineAlarmSettingPayload } from '../types/platform'
|
||||
import { ensureSaveAuthorized } from '../utils/saveGuard'
|
||||
|
||||
defineProps<{ store: any; actions: any }>()
|
||||
|
||||
const lineAlarm = reactive<LineAlarmSettingPayload>({
|
||||
line_no: 1,
|
||||
over_limit_alarm: [
|
||||
{ category: '电压', limit: 180, delay: 180, output_node: '开出1', enabled: true },
|
||||
{ category: '电流', limit: 180, delay: 180, output_node: '开出1', enabled: true },
|
||||
{ category: '差流', limit: 180, delay: 180, output_node: '开出1', enabled: false },
|
||||
{ category: '频率', limit: 180, delay: 180, output_node: '开出1', enabled: false },
|
||||
],
|
||||
fault_alarm: [{ category: 'PT断线', delay: 180, output_node: '开出1', enabled: true }],
|
||||
})
|
||||
|
||||
const aiAlarm = reactive<AiAlarmSettingItem[]>([
|
||||
{
|
||||
channel_no: 1,
|
||||
singal_type: '4-20mA',
|
||||
limit_low: 0,
|
||||
limit_high: 20,
|
||||
delay: 180,
|
||||
output_node: '开出1',
|
||||
enabled: true,
|
||||
},
|
||||
])
|
||||
|
||||
const result = ref('未保存')
|
||||
const saving = ref(false)
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const [lineData, aiData] = await Promise.all([fetchLineAlarmSetting(), fetchAiAlarmSetting()])
|
||||
lineAlarm.line_no = lineData.line_no
|
||||
lineData.over_limit_alarm.forEach((item, index) => {
|
||||
if (lineAlarm.over_limit_alarm[index]) {
|
||||
Object.assign(lineAlarm.over_limit_alarm[index], item)
|
||||
} else {
|
||||
lineAlarm.over_limit_alarm.push(item)
|
||||
}
|
||||
})
|
||||
lineData.fault_alarm.forEach((item, index) => {
|
||||
if (lineAlarm.fault_alarm[index]) {
|
||||
Object.assign(lineAlarm.fault_alarm[index], item)
|
||||
} else {
|
||||
lineAlarm.fault_alarm.push(item)
|
||||
}
|
||||
})
|
||||
aiData.forEach((item, index) => {
|
||||
if (aiAlarm[index]) {
|
||||
Object.assign(aiAlarm[index], item)
|
||||
} else {
|
||||
aiAlarm.push(item)
|
||||
}
|
||||
})
|
||||
result.value = '已加载当前报警设置'
|
||||
} catch (error) {
|
||||
result.value = error instanceof Error ? error.message : '加载报警设置失败'
|
||||
}
|
||||
})
|
||||
|
||||
async function save() {
|
||||
saving.value = true
|
||||
try {
|
||||
const guard = await ensureSaveAuthorized()
|
||||
if (!guard.ok) {
|
||||
result.value = guard.message
|
||||
return
|
||||
}
|
||||
|
||||
const [lineResponse, aiResponse] = await Promise.all([saveLineAlarmSetting(lineAlarm), saveAiAlarmSetting(aiAlarm)])
|
||||
result.value = `${lineResponse.msg} / ${aiResponse.msg}`
|
||||
} catch (error) {
|
||||
result.value = error instanceof Error ? error.message : '保存报警设置失败'
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="panel">
|
||||
<h2>报警设置</h2>
|
||||
<div class="form-grid">
|
||||
<label>线路号<input v-model.number="lineAlarm.line_no" type="number" min="1" max="4" /></label>
|
||||
<label>电压越限<input v-model.number="lineAlarm.over_limit_alarm[0].limit" type="number" /></label>
|
||||
<label>电流越限<input v-model.number="lineAlarm.over_limit_alarm[1].limit" type="number" /></label>
|
||||
<label>差流越限<input v-model.number="lineAlarm.over_limit_alarm[2].limit" type="number" /></label>
|
||||
<label>频率越限<input v-model.number="lineAlarm.over_limit_alarm[3].limit" type="number" /></label>
|
||||
<label>动作延时<input v-model.number="lineAlarm.over_limit_alarm[0].delay" type="number" /></label>
|
||||
<label>输出节点<select v-model="lineAlarm.over_limit_alarm[0].output_node"><option>开出1</option><option>开出2</option></select></label>
|
||||
<label>PT断线延时<input v-model.number="lineAlarm.fault_alarm[0].delay" type="number" /></label>
|
||||
<label>AI通道号<input v-model.number="aiAlarm[0].channel_no" type="number" min="1" max="12" /></label>
|
||||
<label>AI信号类型<input v-model="aiAlarm[0].singal_type" /></label>
|
||||
<label>AI下限<input v-model.number="aiAlarm[0].limit_low" type="number" /></label>
|
||||
<label>AI上限<input v-model.number="aiAlarm[0].limit_high" type="number" /></label>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="primary" :disabled="saving" @click="save">{{ saving ? '保存中...' : '保存报警设置' }}</button>
|
||||
</div>
|
||||
<p>保存结果:{{ result }}</p>
|
||||
</section>
|
||||
</template>
|
||||
@ -1,90 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { fetchChannelConfig, saveChannelConfig } from '../api/platform'
|
||||
import type { ChannelConfigPayload } from '../types/platform'
|
||||
import { ensureSaveAuthorized } from '../utils/saveGuard'
|
||||
|
||||
defineProps<{ store: any; actions: any }>()
|
||||
|
||||
const form = reactive<ChannelConfigPayload>({
|
||||
ai_channel: [{ ch: 1, singal_type: '4-20mA', line_no: 1, type: 'UA', limit_low: 0, limit_high: 20 }],
|
||||
ao_channel: [{ ch: 1, singal_type: '1-5v', line_no: 2, type: 'UA', limit_low: 0, limit_high: 20 }],
|
||||
})
|
||||
|
||||
const result = ref('未保存')
|
||||
const saving = ref(false)
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const data = await fetchChannelConfig()
|
||||
data.ai_channel.forEach((item, index) => {
|
||||
if (form.ai_channel[index]) {
|
||||
Object.assign(form.ai_channel[index], item)
|
||||
} else {
|
||||
form.ai_channel.push(item)
|
||||
}
|
||||
})
|
||||
data.ao_channel.forEach((item, index) => {
|
||||
if (form.ao_channel[index]) {
|
||||
Object.assign(form.ao_channel[index], item)
|
||||
} else {
|
||||
form.ao_channel.push(item)
|
||||
}
|
||||
})
|
||||
result.value = '已加载当前通道配置'
|
||||
} catch (error) {
|
||||
result.value = error instanceof Error ? error.message : '加载通道配置失败'
|
||||
}
|
||||
})
|
||||
|
||||
async function save() {
|
||||
saving.value = true
|
||||
try {
|
||||
const guard = await ensureSaveAuthorized()
|
||||
if (!guard.ok) {
|
||||
result.value = guard.message
|
||||
return
|
||||
}
|
||||
|
||||
const response = await saveChannelConfig(form)
|
||||
result.value = `${response.msg},${response.data.send_status}`
|
||||
} catch (error) {
|
||||
result.value = error instanceof Error ? error.message : '保存通道配置失败'
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="panel">
|
||||
<h2>通道配置</h2>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr><th>通道</th><th>信号类型</th><th>线路</th><th>测量类型</th><th>下限</th><th>上限</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>AI{{ form.ai_channel[0].ch }}</td>
|
||||
<td><input v-model="form.ai_channel[0].singal_type" /></td>
|
||||
<td><input v-model.number="form.ai_channel[0].line_no" type="number" min="1" max="4" /></td>
|
||||
<td><input v-model="form.ai_channel[0].type" /></td>
|
||||
<td><input v-model.number="form.ai_channel[0].limit_low" type="number" /></td>
|
||||
<td><input v-model.number="form.ai_channel[0].limit_high" type="number" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>AO{{ form.ao_channel[0].ch }}</td>
|
||||
<td><input v-model="form.ao_channel[0].singal_type" /></td>
|
||||
<td><input v-model.number="form.ao_channel[0].line_no" type="number" min="1" max="4" /></td>
|
||||
<td><input v-model="form.ao_channel[0].type" /></td>
|
||||
<td><input v-model.number="form.ao_channel[0].limit_low" type="number" /></td>
|
||||
<td><input v-model.number="form.ao_channel[0].limit_high" type="number" /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="actions">
|
||||
<button class="primary" :disabled="saving" @click="save">{{ saving ? '保存中...' : '保存通道配置' }}</button>
|
||||
</div>
|
||||
<p>保存结果:{{ result }}</p>
|
||||
</section>
|
||||
</template>
|
||||
@ -1,28 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue"
|
||||
import { controlSwitch } from "../api/platform"
|
||||
|
||||
defineProps<{ store: any; actions: any }>()
|
||||
|
||||
const channel = ref(1)
|
||||
const result = ref("等待下发")
|
||||
|
||||
async function sendControl(action: number) {
|
||||
const response = await controlSwitch(channel.value, action)
|
||||
result.value = response.data.control_status
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="panel">
|
||||
<h2>控制指令</h2>
|
||||
<div class="form-grid">
|
||||
<label>开关通道<input v-model="channel" type="number" min="1" max="12" /></label>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="primary" @click="sendControl(1)">合闸</button>
|
||||
<button class="primary" @click="sendControl(0)">分闸</button>
|
||||
</div>
|
||||
<p>执行结果:{{ result }}</p>
|
||||
</section>
|
||||
</template>
|
||||
@ -1,104 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { fetchDeviceConfig, saveDeviceConfig } from '../api/platform'
|
||||
import type { DeviceConfigPayload } from '../types/platform'
|
||||
import { ensureSaveAuthorized } from '../utils/saveGuard'
|
||||
|
||||
defineProps<{ store: any; actions: any }>()
|
||||
|
||||
const form = reactive<DeviceConfigPayload>({
|
||||
password: '123456',
|
||||
hardware_version: {
|
||||
board_version: 'B001.001.001',
|
||||
display_version: 'S001.001.001',
|
||||
other_version: 'Y001.001.001',
|
||||
},
|
||||
software_version: {
|
||||
display_program: '001.001.001',
|
||||
communication_program: '001.001.001',
|
||||
measurement_program: '001.001.001',
|
||||
},
|
||||
net: [
|
||||
{ nic: '网卡一', ip: '192.168.1.10', mask: '255.255.255.0', gateway: '192.168.1.1', protocol: 'Modbus TCP' },
|
||||
{ nic: '网卡二', ip: '192.168.1.56', mask: '255.255.255.255', gateway: '192.168.1.56', protocol: 'Modbus TCP' },
|
||||
],
|
||||
uart: [
|
||||
{ port: 'COM1', baud: 9600, parity: 'NONE', data_bits: 8, stop_bits: 1, protocol: '' },
|
||||
{ port: 'COM2', baud: 115200, parity: 'NONE', data_bits: 8, stop_bits: 1, protocol: 'Modbus RTU' },
|
||||
],
|
||||
})
|
||||
|
||||
const result = ref('未保存')
|
||||
const saving = ref(false)
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const data = await fetchDeviceConfig()
|
||||
form.password = data.password
|
||||
Object.assign(form.hardware_version, data.hardware_version)
|
||||
Object.assign(form.software_version, data.software_version)
|
||||
data.net.forEach((item, index) => {
|
||||
if (form.net[index]) {
|
||||
Object.assign(form.net[index], item)
|
||||
} else {
|
||||
form.net.push(item)
|
||||
}
|
||||
})
|
||||
data.uart.forEach((item, index) => {
|
||||
if (form.uart[index]) {
|
||||
Object.assign(form.uart[index], item)
|
||||
} else {
|
||||
form.uart.push(item)
|
||||
}
|
||||
})
|
||||
result.value = '已加载当前设备配置'
|
||||
} catch (error) {
|
||||
result.value = error instanceof Error ? error.message : '加载设备配置失败'
|
||||
}
|
||||
})
|
||||
|
||||
async function save() {
|
||||
saving.value = true
|
||||
try {
|
||||
const guard = await ensureSaveAuthorized()
|
||||
if (!guard.ok) {
|
||||
result.value = guard.message
|
||||
return
|
||||
}
|
||||
|
||||
const response = await saveDeviceConfig(form)
|
||||
result.value = `${response.msg},${response.data.send_status}`
|
||||
} catch (error) {
|
||||
result.value = error instanceof Error ? error.message : '保存设备配置失败'
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="panel">
|
||||
<h2>设备基础配置</h2>
|
||||
<div class="form-grid">
|
||||
<label>操作密码<input v-model="form.password" type="password" /></label>
|
||||
<label>板卡版本<input v-model="form.hardware_version.board_version" /></label>
|
||||
<label>显示版本<input v-model="form.hardware_version.display_version" /></label>
|
||||
<label>其他版本<input v-model="form.hardware_version.other_version" /></label>
|
||||
<label>显示程序版本<input v-model="form.software_version.display_program" /></label>
|
||||
<label>通信程序版本<input v-model="form.software_version.communication_program" /></label>
|
||||
<label>测量程序版本<input v-model="form.software_version.measurement_program" /></label>
|
||||
<label>网卡一 IP<input v-model="form.net[0].ip" /></label>
|
||||
<label>网卡一 掩码<input v-model="form.net[0].mask" /></label>
|
||||
<label>网卡一 网关<input v-model="form.net[0].gateway" /></label>
|
||||
<label>网卡二 IP<input v-model="form.net[1].ip" /></label>
|
||||
<label>网卡二 协议<input v-model="form.net[1].protocol" /></label>
|
||||
<label>串口一波特率<input v-model.number="form.uart[0].baud" type="number" /></label>
|
||||
<label>串口二波特率<input v-model.number="form.uart[1].baud" type="number" /></label>
|
||||
<label>串口二协议<input v-model="form.uart[1].protocol" /></label>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="primary" :disabled="saving" @click="save">{{ saving ? '保存中...' : '保存设备配置' }}</button>
|
||||
</div>
|
||||
<p>保存结果:{{ result }}</p>
|
||||
</section>
|
||||
</template>
|
||||
@ -1,35 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{ store: any; actions: any }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="panel">
|
||||
<h2>实时数据</h2>
|
||||
<div class="metrics" style="margin-bottom: 12px">
|
||||
<div class="metric">
|
||||
<div class="label">数据源</div>
|
||||
<div class="value">{{ store.realtimeSource }}</div>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<div class="label">连接状态</div>
|
||||
<div class="value">{{ store.realtimeConnected ? 'WebSocket 已连接' : 'HTTP 轮询回退' }}</div>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<div class="label">最后更新时间</div>
|
||||
<div class="value">{{ store.realtimeUpdatedAt || '--' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="store.realtime" class="grid">
|
||||
<div v-for="line in store.realtime.line_list" :key="line.line_no" class="panel">
|
||||
<h3>线路 {{ line.line_no }}</h3>
|
||||
<div class="metrics">
|
||||
<div class="metric"><div class="label">一次电压 Ua</div><div class="value">{{ line.pri_val.Ua }}</div></div>
|
||||
<div class="metric"><div class="label">一次电流 Ia</div><div class="value">{{ line.pri_val.Ia }}</div></div>
|
||||
<div class="metric"><div class="label">总有功 Pt</div><div class="value">{{ line.pri_val.Pt }}</div></div>
|
||||
<div class="metric"><div class="label">频率</div><div class="value">{{ line.pri_val.frq }}</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p v-else>正在等待实时数据...</p>
|
||||
</section>
|
||||
</template>
|
||||
@ -1,27 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{ store: any; actions: any }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="panel">
|
||||
<div class="section-header">
|
||||
<h2>设备状态</h2>
|
||||
<div class="actions">
|
||||
<button class="primary" :disabled="store.statusLoading" @click="actions.refreshStatus()">
|
||||
{{ store.statusLoading ? '刷新中...' : '刷新状态' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="store.status">
|
||||
<div class="metrics">
|
||||
<div class="metric"><div class="label">自检</div><div class="value">{{ store.status.self_check }}</div></div>
|
||||
<div class="metric"><div class="label">网口1</div><div class="value">{{ store.status.net1 }}</div></div>
|
||||
<div class="metric"><div class="label">网口2</div><div class="value">{{ store.status.net2 }}</div></div>
|
||||
<div class="metric"><div class="label">串口1</div><div class="value">{{ store.status.uart1 }}</div></div>
|
||||
<div class="metric"><div class="label">串口2</div><div class="value">{{ store.status.uart2 }}</div></div>
|
||||
</div>
|
||||
<p class="hint">最后刷新:{{ store.statusUpdatedAt || '--' }}</p>
|
||||
</template>
|
||||
<p v-else>正在加载状态...</p>
|
||||
</section>
|
||||
</template>
|
||||
@ -1,48 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from "vue"
|
||||
import { fetchSystemConfig, saveSystemConfig } from "../api/platform"
|
||||
import { ensureSaveAuthorized } from "../utils/saveGuard"
|
||||
|
||||
defineProps<{ store: any; actions: any }>()
|
||||
|
||||
const form = reactive({
|
||||
time_sync: "auto",
|
||||
brightness: 80,
|
||||
screen_saver: 60,
|
||||
})
|
||||
const result = ref("未保存")
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const data = await fetchSystemConfig()
|
||||
Object.assign(form, data)
|
||||
result.value = "已加载当前系统设置"
|
||||
} catch (error) {
|
||||
result.value = error instanceof Error ? error.message : "加载系统设置失败"
|
||||
}
|
||||
})
|
||||
|
||||
async function save() {
|
||||
const guard = await ensureSaveAuthorized()
|
||||
if (!guard.ok) {
|
||||
result.value = guard.message
|
||||
return
|
||||
}
|
||||
|
||||
const response = await saveSystemConfig(form)
|
||||
result.value = response.msg
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="panel">
|
||||
<h2>系统设置</h2>
|
||||
<div class="form-grid">
|
||||
<label>对时模式<select v-model="form.time_sync"><option value="auto">自动</option><option value="manual">手动</option></select></label>
|
||||
<label>亮度<input v-model="form.brightness" type="number" min="0" max="100" /></label>
|
||||
<label>屏保时间<input v-model="form.screen_saver" type="number" min="0" /></label>
|
||||
</div>
|
||||
<div class="actions"><button class="primary" @click="save">保存系统设置</button></div>
|
||||
<p>保存结果:{{ result }}</p>
|
||||
</section>
|
||||
</template>
|
||||
@ -20,6 +20,7 @@ const channelList = ref([
|
||||
|
||||
const nodeOptions = ref(['开出一', '开出二', '开出三', '开出四', '开出五', '开出六', '开出七', '开出八', '开出九', '开出十', '开出十一', '开出十二'])
|
||||
const isswitch = ref(false)
|
||||
const dialogVisible = ref(false)
|
||||
const handleSave = () => {
|
||||
ElMessageBox.prompt('请输入密码', '保存', {
|
||||
confirmButtonText: '确定',
|
||||
@ -39,10 +40,13 @@ const handleSave = () => {
|
||||
ElMessage.success('保存成功')
|
||||
init()
|
||||
isswitch.value = false
|
||||
} else {
|
||||
ElMessage.error('保存失败')
|
||||
}
|
||||
})
|
||||
}else{
|
||||
ElMessage.error('密码错误,不能修改!')
|
||||
isswitch.value = false
|
||||
dialogVisible.value = true
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -84,7 +88,9 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="row" v-for="(item, idx) in channelList" :key="idx">
|
||||
<div class="cell cell-no">{{ item.channel_no }}</div>
|
||||
<div class="cell cell-type" style="background: #ffffff;">{{ item.singal_type }}</div>
|
||||
<div class="cell cell-type" style="background: #ffffff;">
|
||||
<el-input v-model="item.singal_type" placeholder="" />
|
||||
</div>
|
||||
<div class="cell cell-line" style="background: #ffffff;">
|
||||
<el-input-number v-model="item.limit_low" style="width: 100%;" :controls="false" />
|
||||
</div>
|
||||
@ -108,6 +114,12 @@ onMounted(() => {
|
||||
<div class="btn-wrap">
|
||||
<button class="save-btn" @click="handleSave">保存</button>
|
||||
</div>
|
||||
<el-dialog v-model="dialogVisible" :close-on-click-modal="false" :show-close="false" title="错误提示" width="300">
|
||||
<div style="color: #FF4D4F;font-size: 16px;text-align: center;">原密码验证错误!</div>
|
||||
<template #footer>
|
||||
<el-button type="primary" @click="dialogVisible = false">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -19,6 +19,8 @@ const channelList: any = ref([
|
||||
const aoChannelList: any = ref([])
|
||||
const lineOptions = ref([{ label: '线路一', value: 1 }, { label: '线路二', value: 2 }, { label: '线路三', value: 3 }, { label: '线路四', value: 4 }])
|
||||
const categoryOptions = ref(['UA', 'UB', 'UC'])
|
||||
const categoryOptions2 = ref(['IA', 'IB', 'IC'])
|
||||
const dialogVisible = ref(false)
|
||||
const isswitch = ref(false)
|
||||
const handleSave = () => {
|
||||
ElMessageBox.prompt('请输入密码', '保存', {
|
||||
@ -42,12 +44,15 @@ const handleSave = () => {
|
||||
if (res.data) {
|
||||
ElMessage.success('保存成功')
|
||||
isswitch.value = false
|
||||
} else {
|
||||
ElMessage.error('保存失败')
|
||||
}
|
||||
}).catch(err => {
|
||||
isswitch.value = false
|
||||
})
|
||||
} else {
|
||||
ElMessage.error('密码错误,不能修改!')
|
||||
isswitch.value = false
|
||||
dialogVisible.value = true
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -68,6 +73,7 @@ function init() {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
@ -87,7 +93,9 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="row" v-for="(item, idx) in channelList" :key="idx">
|
||||
<div class="cell cell-no">{{ item.ch }}</div>
|
||||
<div class="cell cell-type" style="background: #ffffff;">{{ item.singal_type }}</div>
|
||||
<div class="cell cell-type" style="background: #ffffff;">
|
||||
<el-input v-model="item.singal_type" placeholder="" />
|
||||
</div>
|
||||
<div class="cell cell-line" style="background: #ffffff;">
|
||||
<el-select v-model="item.line_no">
|
||||
<el-option v-for="line in lineOptions" :key="line.value" :value="line.value"
|
||||
@ -96,7 +104,7 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="cell cell-category" style="background: #ffffff;">
|
||||
<el-select v-model="item.type">
|
||||
<el-option v-for="cat in categoryOptions" :key="cat" :value="cat" :label="cat"></el-option>
|
||||
<el-option v-for="cat in (item.singal_type.includes('mA') ? categoryOptions2 : categoryOptions)" :key="cat" :value="cat" :label="cat"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="cell cell-low" style="background: #ffffff;">
|
||||
@ -111,6 +119,16 @@ onMounted(() => {
|
||||
<div class="btn-wrap">
|
||||
<button class="save-btn" @click="handleSave">保存</button>
|
||||
</div>
|
||||
<el-dialog v-model="dialogVisible" :close-on-click-modal="false" :show-close="false" title="错误提示" width="300">
|
||||
<div style="color: #FF4D4F;font-size: 16px;text-align: center;">原密码验证错误!</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="dialogVisible = false">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -239,5 +257,7 @@ onMounted(() => {
|
||||
|
||||
:deep(.el-input__inner) {
|
||||
text-align: center !important;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -34,21 +34,24 @@ function formatTime(dateStr: string): string {
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
||||
}
|
||||
const tableData = computed(() => {
|
||||
const list = state.alarms[state.alarms.length - 1] || {}
|
||||
const arr = []
|
||||
let reslist:any = {}
|
||||
if(list.alarm_type == 'line_alarm'){
|
||||
const alarms = state.alarms || []
|
||||
const firstThree = alarms.slice(0, 2)
|
||||
return firstThree.map(list => {
|
||||
const reslist: any = {}
|
||||
if (list.alarm_type == 'line_alarm') {
|
||||
reslist.name = `线路${list?.no || 1}`
|
||||
}else if(list.alarm_type == 'ai_alarm'){
|
||||
} else if (list.alarm_type == 'ai_alarm') {
|
||||
reslist.name = `通道${list?.no || 1}`
|
||||
} else if(list.alarm_type == 'operate_alarm'){
|
||||
} else if (list.alarm_type == 'operate_alarm') {
|
||||
reslist.name = ''
|
||||
}
|
||||
reslist.typeName = list.type
|
||||
reslist.content = list.content
|
||||
reslist.time = list.time ? formatTime(list.time) : ''
|
||||
reslist.level = list.level || ''
|
||||
return [reslist]
|
||||
reslist.id = list.id || '0'
|
||||
return reslist
|
||||
})
|
||||
})
|
||||
function init(){
|
||||
fetchChannelConfig().then(res => {
|
||||
@ -191,7 +194,7 @@ onMounted(() => {
|
||||
|
||||
.container-bottom-box {
|
||||
width: 100%;
|
||||
height: calc(100vh - 660px);
|
||||
height: calc(100vh - 646px);
|
||||
padding: 20px;
|
||||
background: #ffffff;
|
||||
box-shadow: 0px 0px 10px rgba(219, 225, 236, 1);
|
||||
|
||||
@ -31,8 +31,8 @@ const currentValues = computed<ValueGroup | null>(() => {
|
||||
})
|
||||
|
||||
const frequency = computed(() => {
|
||||
if (!currentValues.value) return '50'
|
||||
return currentValues.value.frq
|
||||
if (!currentValues.value) return '50.000'
|
||||
return currentValues.value.frq.toFixed(3)
|
||||
})
|
||||
|
||||
const infoList = computed(() => {
|
||||
@ -50,45 +50,45 @@ const infoList = computed(() => {
|
||||
return [
|
||||
{
|
||||
name: '单项电压(V)',
|
||||
a: values.Ua,
|
||||
b: values.Ub,
|
||||
c: values.Uc,
|
||||
a: values.Ua.toFixed(3),
|
||||
b: values.Ub.toFixed(3),
|
||||
c: values.Uc.toFixed(3),
|
||||
total: '',
|
||||
},
|
||||
{
|
||||
name: '单相电流(A)',
|
||||
a: values.Ia,
|
||||
b: values.Ib,
|
||||
c: values.Ic,
|
||||
a: values.Ia.toFixed(3),
|
||||
b: values.Ib.toFixed(3),
|
||||
c: values.Ic.toFixed(3),
|
||||
total: '',
|
||||
},
|
||||
{
|
||||
name: '有功功率(kw)',
|
||||
a: values.Pa,
|
||||
b: values.Pb,
|
||||
c: values.Pc,
|
||||
total: values.Pt
|
||||
a: values.Pa.toFixed(2),
|
||||
b: values.Pb.toFixed(2),
|
||||
c: values.Pc.toFixed(2),
|
||||
total: values.Pt.toFixed(2)
|
||||
},
|
||||
{
|
||||
name: '无功功率(kvar)',
|
||||
a: values.Qa,
|
||||
b: values.Qb,
|
||||
c: values.Qc,
|
||||
total: values.Qt
|
||||
a: values.Qa.toFixed(2),
|
||||
b: values.Qb.toFixed(2),
|
||||
c: values.Qc.toFixed(2),
|
||||
total: values.Qt.toFixed(2)
|
||||
},
|
||||
{
|
||||
name: '视在功率(kVA)',
|
||||
a: values.Sa,
|
||||
b: values.Sb,
|
||||
c: values.Sc,
|
||||
total: values.St
|
||||
a: values.Sa.toFixed(2),
|
||||
b: values.Sb.toFixed(2),
|
||||
c: values.Sc.toFixed(2),
|
||||
total: values.St.toFixed(2)
|
||||
},
|
||||
{
|
||||
name: '功率因数(cos)',
|
||||
a: values.PFa,
|
||||
b: values.PFb,
|
||||
c: values.PFc,
|
||||
total: values.PFt
|
||||
a: values.PFa.toFixed(3),
|
||||
b: values.PFb.toFixed(3),
|
||||
c: values.PFc.toFixed(3),
|
||||
total: values.PFt.toFixed(3)
|
||||
},
|
||||
]
|
||||
})
|
||||
@ -100,9 +100,9 @@ const infoData = computed(() => {
|
||||
}
|
||||
return {
|
||||
name: '线电压(V)',
|
||||
a: values?.Uab,
|
||||
b: values?.Ubc,
|
||||
c: values?.Uca,
|
||||
a: values?.Uab?.toFixed(3),
|
||||
b: values?.Ubc?.toFixed(3),
|
||||
c: values?.Uca?.toFixed(3),
|
||||
}
|
||||
})
|
||||
|
||||
@ -118,28 +118,24 @@ function formatTime(dateStr: string): string {
|
||||
}
|
||||
|
||||
const tableData = computed(() => {
|
||||
const list = state.alarms[state.alarms.length - 1] || {}
|
||||
const arr = []
|
||||
let reslist:any = {}
|
||||
if(list.alarm_type == 'line_alarm'){
|
||||
const alarms = state.alarms || []
|
||||
const firstThree = alarms.slice(0, 2)
|
||||
return firstThree.map(list => {
|
||||
const reslist: any = {}
|
||||
if (list.alarm_type == 'line_alarm') {
|
||||
reslist.name = `线路${list?.no || 1}`
|
||||
}else if(list.alarm_type == 'ai_alarm'){
|
||||
} else if (list.alarm_type == 'ai_alarm') {
|
||||
reslist.name = `通道${list?.no || 1}`
|
||||
} else if(list.alarm_type == 'operate_alarm'){
|
||||
} else if (list.alarm_type == 'operate_alarm') {
|
||||
reslist.name = ''
|
||||
}
|
||||
reslist.typeName = list.type
|
||||
reslist.content = list.content
|
||||
reslist.time = list.time ? formatTime(list.time) : ''
|
||||
reslist.level = list.level || ''
|
||||
return [reslist]
|
||||
// return state.alarms.slice(0, 10).map((alarm, index) => ({
|
||||
// name: `线路${currentLineData.value?.line_no || 1}`,
|
||||
// typeName: alarm.type,
|
||||
// content: alarm.content,
|
||||
// time: alarm.time,
|
||||
// ts: '0',
|
||||
// }))
|
||||
reslist.id = list.id || '0'
|
||||
return reslist
|
||||
})
|
||||
})
|
||||
|
||||
function handleClick(name: string) {
|
||||
@ -218,7 +214,7 @@ onMounted(() => {
|
||||
<div class="analog-quantity-container-bottom">
|
||||
<div class="top-title">报警信息</div>
|
||||
<div class="container-bottom-box">
|
||||
<div v-for="(item, index) in tableData" :key="item.name" class="container-bottom-box-line1">
|
||||
<div v-for="(item, index) in tableData" :key="item.id" class="container-bottom-box-line1">
|
||||
<div style="width: 8%;text-align: center;">{{ index + 1 }}</div>
|
||||
<div style="width: 14%;text-align: center;">{{ item.name }}</div>
|
||||
<div style="width: 20%;text-align: center;">{{ item.typeName }}</div>
|
||||
@ -349,7 +345,7 @@ onMounted(() => {
|
||||
|
||||
.container-bottom-box {
|
||||
width: 100%;
|
||||
height: calc(100vh - 660px);
|
||||
height: calc(100vh - 645px);
|
||||
padding: 20px;
|
||||
background: #ffffff;
|
||||
box-shadow: 0px 0px 10px rgba(219, 225, 236, 1);
|
||||
|
||||
@ -18,7 +18,8 @@ const channelList: any = ref([
|
||||
])
|
||||
const lineOptions = ref([{ label: '线路一', value: 1 }, { label: '线路二', value: 2 }, { label: '线路三', value: 3 }, { label: '线路四', value: 4 }])
|
||||
const categoryOptions = ref(['UA', 'UB', 'UC'])
|
||||
|
||||
const categoryOptions2 = ref(['IA', 'IB', 'IC'])
|
||||
const dialogVisible = ref(false)
|
||||
const aiChannelList = ref([])
|
||||
function init() {
|
||||
fetchChannelConfig().then((res: any) => {
|
||||
@ -59,12 +60,15 @@ const handleSave = () => {
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('保存成功')
|
||||
isswitch.value = false
|
||||
} else {
|
||||
ElMessage.error('保存失败')
|
||||
}
|
||||
}).catch(err => {
|
||||
isswitch.value = false
|
||||
})
|
||||
} else {
|
||||
ElMessage.error('密码错误,不能修改!')
|
||||
isswitch.value = false
|
||||
dialogVisible.value = true
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -88,7 +92,9 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="row" v-for="(item, idx) in channelList" :key="idx">
|
||||
<div class="cell cell-no">{{ item.ch }}</div>
|
||||
<div class="cell cell-type" style="background: #ffffff;">{{ item.singal_type }}</div>
|
||||
<div class="cell cell-type" style="background: #ffffff;">
|
||||
<el-input v-model="item.singal_type" placeholder="" />
|
||||
</div>
|
||||
<div class="cell cell-line" style="background: #ffffff;">
|
||||
<el-select v-model="item.line_no">
|
||||
<el-option v-for="line in lineOptions" :key="line.value" :value="line.value"
|
||||
@ -97,7 +103,8 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="cell cell-category" style="background: #ffffff;">
|
||||
<el-select v-model="item.type">
|
||||
<el-option v-for="cat in categoryOptions" :key="cat" :value="cat" :label="cat"></el-option>
|
||||
<el-option v-for="cat in (item.singal_type.includes('mA') ? categoryOptions2 : categoryOptions)" :key="cat"
|
||||
:value="cat" :label="cat"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="cell cell-low" style="background: #ffffff;">
|
||||
@ -112,6 +119,16 @@ onMounted(() => {
|
||||
<div class="btn-wrap">
|
||||
<button class="save-btn" @click="handleSave">保存</button>
|
||||
</div>
|
||||
<el-dialog v-model="dialogVisible" :close-on-click-modal="false" :show-close="false" title="错误提示" width="300">
|
||||
<div style="color: #FF4D4F;font-size: 16px;text-align: center;">原密码验证错误!</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="dialogVisible = false">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -63,7 +63,8 @@ const rtuProtocolOptions = [
|
||||
{ label: 'Modbus RTU', value: 'Modbus RTU' },
|
||||
{ label: 'IEC101 ', value: 'IEC101' }
|
||||
]
|
||||
|
||||
const isswitch = ref(false)
|
||||
const dialogVisible = ref(false)
|
||||
// 保存
|
||||
const handleSave = () => {
|
||||
ElMessageBox.prompt('请输入密码', '保存', {
|
||||
@ -74,9 +75,11 @@ const handleSave = () => {
|
||||
.then(({ value }) => {
|
||||
verifyAccessPassword(value).then((res: any) => {
|
||||
if (res.data) {
|
||||
|
||||
saveDeviceNetConfig(formData.value).then((res: any) => {
|
||||
console.log(res)
|
||||
if (isswitch.value) {
|
||||
return
|
||||
}
|
||||
isswitch.value = true
|
||||
if (res.code == 200) {
|
||||
saveDevicePortConfig(formData2.value).then((res: any) => {
|
||||
if (res.code == 200) {
|
||||
@ -84,25 +87,26 @@ const handleSave = () => {
|
||||
type: 'success',
|
||||
message: `保存成功`,
|
||||
})
|
||||
isswitch.value = false
|
||||
} else {
|
||||
ElMessage({
|
||||
type: 'info',
|
||||
type: 'error',
|
||||
message: '串口设置保存失败',
|
||||
})
|
||||
isswitch.value = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
ElMessage({
|
||||
type: 'info',
|
||||
type: 'error',
|
||||
message: '常规配置保存失败',
|
||||
})
|
||||
isswitch.value = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
ElMessage({
|
||||
type: 'info',
|
||||
message: '密码错误,不能修改!',
|
||||
})
|
||||
isswitch.value = false
|
||||
dialogVisible.value = true
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -232,6 +236,12 @@ onMounted(() => {
|
||||
<el-button type="primary" style="background-color: #0099ff;width: 150px;height: 40px;"
|
||||
@click="handleSave">保存</el-button>
|
||||
</div>
|
||||
<el-dialog v-model="dialogVisible" :close-on-click-modal="false" :show-close="false" title="错误提示" width="300">
|
||||
<div style="color: #FF4D4F;font-size: 16px;text-align: center;">原密码验证错误!</div>
|
||||
<template #footer>
|
||||
<el-button type="primary" @click="dialogVisible = false">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { fetchAlarmHistory } from '@/api/platform'
|
||||
const formData = ref({
|
||||
const formData: any = ref({
|
||||
no: null,
|
||||
type: '',
|
||||
timeRange: [],
|
||||
@ -44,15 +44,31 @@ function init() {
|
||||
const params: any = {
|
||||
page: pagination.value.currentPage,
|
||||
size: pagination.value.pageSize,
|
||||
}
|
||||
if (formData.value.timeRange && formData.value.timeRange.length > 0) {
|
||||
params.start_time = formData.value.timeRange[0]
|
||||
params.end_time = formData.value.timeRange[1]
|
||||
}
|
||||
fetchAlarmHistory(params).then((res: any) => {
|
||||
tableData.value = res
|
||||
})
|
||||
}
|
||||
const formatDate = (date: Date): string => {
|
||||
const pad = (n: number): string => n.toString().padStart(2, '0')
|
||||
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
|
||||
}
|
||||
|
||||
const getDefaultTimeRange = (): [string, string] => {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
start.setDate(start.getDate() - 7)
|
||||
return [formatDate(start), formatDate(end)]
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
formData.value.no = null
|
||||
formData.value.type = ''
|
||||
formData.value.timeRange = []
|
||||
formData.value.timeRange = getDefaultTimeRange()
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -22,6 +22,8 @@ const handleSave = async () => {
|
||||
saveSystemConfig(form.value).then(res => {
|
||||
if(res.code === 200){
|
||||
ElMessage.success('保存成功')
|
||||
} else {
|
||||
ElMessage.error('保存失败')
|
||||
}
|
||||
isswitch.value = false
|
||||
})
|
||||
|
||||
@ -141,6 +141,7 @@ const init = () => {
|
||||
})
|
||||
}
|
||||
const isswitch = ref(false)
|
||||
const dialogVisible = ref(false)
|
||||
const handleSave = () => {
|
||||
ElMessageBox.prompt('请输入密码', '保存', {
|
||||
confirmButtonText: '确定',
|
||||
@ -160,10 +161,13 @@ const handleSave = () => {
|
||||
ElMessage.success('保存成功')
|
||||
init()
|
||||
isswitch.value = false
|
||||
} else {
|
||||
ElMessage.error('保存失败')
|
||||
}
|
||||
})
|
||||
}else{
|
||||
ElMessage.error('密码错误,不能修改!')
|
||||
isswitch.value = false
|
||||
dialogVisible.value = true
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -307,6 +311,12 @@ const handleSave = () => {
|
||||
</div>
|
||||
<el-button type="primary" class="save-btn" @click="handleSave">保存</el-button>
|
||||
</div>
|
||||
<el-dialog v-model="dialogVisible" :close-on-click-modal="false" :show-close="false" title="错误提示" width="300">
|
||||
<div style="color: #FF4D4F;font-size: 16px;text-align: center;">原密码验证错误!</div>
|
||||
<template #footer>
|
||||
<el-button type="primary" @click="dialogVisible = false">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -1,193 +0,0 @@
|
||||
<!-- <script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { login } from '@/api/auth'
|
||||
import { ElMessage } from 'element-plus'
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const loginForm = ref({
|
||||
account: '',
|
||||
password: ''
|
||||
})
|
||||
const loading = ref(false)
|
||||
const error = ref('')
|
||||
const loginFormRef = ref()
|
||||
const loginRules = reactive({
|
||||
account: [
|
||||
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: '请输入密码', trigger: 'blur' },
|
||||
]
|
||||
})
|
||||
const handleLogin = () => {
|
||||
loginFormRef.value.validate((valid: any) => {
|
||||
if (valid) {
|
||||
loading.value = true;
|
||||
const params = {
|
||||
account: loginForm.value.account,
|
||||
password: loginForm.value.password
|
||||
};
|
||||
login(params)
|
||||
.then((response: any) => {
|
||||
localStorage.setItem('token', response.token)
|
||||
localStorage.setItem('username', response.user.username)
|
||||
localStorage.setItem('account', response.user.account)
|
||||
const redirect = (route.query.redirect as string) || '/dashboard'
|
||||
router.push(redirect)
|
||||
})
|
||||
.catch((error: any) => {
|
||||
ElMessage.error(error.message || '登录失败,请检查用户名和密码');
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="login-container">
|
||||
<div class="login-title-box">
|
||||
<div class="login-title">PEX50K台架试验数据监控系统</div>
|
||||
</div>
|
||||
<div class="login-form">
|
||||
<div class="login-form-title">欢迎登录</div>
|
||||
|
||||
<el-form ref="loginFormRef" :model="loginForm" :rules="loginRules" class="login-form-box">
|
||||
<el-form-item prop="account">
|
||||
<el-input v-model="loginForm.account" placeholder="请输入用户名">
|
||||
<template #prefix>
|
||||
<img src="../../assets/login/yh.png" alt="" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input v-model="loginForm.password" type="password" placeholder="请输入密码">
|
||||
<template #prefix>
|
||||
<img src="../../assets/login/mm.png" alt="" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="login-btn" @click="handleLogin">
|
||||
<img src="../../assets/login/loginbt.png" alt="">
|
||||
<span class="login-text">登录</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.login-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-repeat: no-repeat;
|
||||
height: 100vh;
|
||||
padding: 16px;
|
||||
background-image: url('../../assets/login/dl_bg.png');
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.login-title-box {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.login-title {
|
||||
font-size: 50px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 4px;
|
||||
background: linear-gradient(to bottom, #FFFFFF 0%, #C3E3FF 75%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
color: transparent;
|
||||
|
||||
}
|
||||
|
||||
.login-form {
|
||||
width: 650px;
|
||||
height: 350px;
|
||||
background-image: url('../../assets/login/dl_kuang.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-position: right;
|
||||
position: relative;
|
||||
top: 80px;
|
||||
right: -385px;
|
||||
}
|
||||
|
||||
.login-form-title {
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
font-weight: 400;
|
||||
color: #FFFFFF;
|
||||
margin-top: 35px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.login-form-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.login-form-box {
|
||||
:deep(.el-input__wrapper) {
|
||||
width: 300px;
|
||||
height: 46px;
|
||||
background-color: transparent;
|
||||
border-radius: 4px;
|
||||
/* border: 1px solid rgba(0, 153, 255, 0.5); */
|
||||
box-shadow: 0 0 0 1px rgba(0, 153, 255, 0.5) inset;
|
||||
position: relative;
|
||||
top: 30px;
|
||||
}
|
||||
|
||||
:deep(.el-input__inner) {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
:deep(.el-input__prefix-inner>:last-child) {
|
||||
margin-right: 10px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__error) {
|
||||
padding-top: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-btn img {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
right: -177px;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
.login-text {
|
||||
position: absolute;
|
||||
left: 305px;
|
||||
top: 267px;
|
||||
font-size: 20px;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style> -->
|
||||
@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive,onMounted } from 'vue'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { verifyAccessPassword,saveDeviceConfig,fetchDeviceConfig } from '@/api/platform'
|
||||
import { verifyAccessPassword, saveDeviceConfig, fetchDeviceConfig, saveDevicePassword } from '@/api/platform'
|
||||
import { ElMessage } from 'element-plus'
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
@ -19,7 +19,17 @@ const rules: FormRules = {
|
||||
],
|
||||
newPassword: [
|
||||
{ required: true, message: '请输入新密码', trigger: 'blur' },
|
||||
{ min: 6, max: 20, message: '密码长度需在 6~20 位之间', trigger: 'blur' }
|
||||
{ min: 6, max: 6, message: '密码长度需 6位', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (!/^\d{6}$/.test(value)) {
|
||||
callback(new Error('密码必须为6位数字'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: '请再次输入新密码', trigger: 'blur' },
|
||||
@ -36,6 +46,10 @@ const rules: FormRules = {
|
||||
]
|
||||
}
|
||||
const isSubmit = ref(false)
|
||||
const dialogVisible = ref(false)
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
// 提交保存
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
@ -45,16 +59,8 @@ const handleSubmit = async () => {
|
||||
isSubmit.value = true
|
||||
verifyAccessPassword(form.oldPassword).then(res => {
|
||||
if (res.data) {
|
||||
// ElMessage({
|
||||
// type: 'success',
|
||||
// message: '原密码验证成功',
|
||||
// })
|
||||
saveDeviceConfig({
|
||||
saveDevicePassword({
|
||||
password: form.newPassword,
|
||||
hardware_version: deviceConfig.value.hardware_version,
|
||||
software_version: deviceConfig.value.software_version,
|
||||
net: deviceConfig.value.net,
|
||||
uart: deviceConfig.value.uart,
|
||||
}).then(res => {
|
||||
if (res.data) {
|
||||
ElMessage({
|
||||
@ -64,7 +70,7 @@ const handleSubmit = async () => {
|
||||
isSubmit.value = false
|
||||
} else {
|
||||
ElMessage({
|
||||
type: 'info',
|
||||
type: 'error',
|
||||
message: '密码设置失败',
|
||||
})
|
||||
isSubmit.value = false
|
||||
@ -72,27 +78,16 @@ const handleSubmit = async () => {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '原密码验证失败',
|
||||
})
|
||||
isSubmit.value = false
|
||||
dialogVisible.value = true
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function init() {
|
||||
fetchDeviceConfig().then(res => {
|
||||
if (res) {
|
||||
deviceConfig.value = res
|
||||
}
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
init()
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -122,9 +117,20 @@ onMounted(() => {
|
||||
|
||||
|
||||
<!-- 保存按钮 -->
|
||||
<el-button type="primary" style="background-color: #0099ff;width: 150px;height: 40px;" class="save-btn" @click="handleSubmit">
|
||||
<el-button type="primary" style="background-color: #0099ff;width: 150px;height: 40px;" class="save-btn"
|
||||
@click="handleSubmit">
|
||||
保存
|
||||
</el-button>
|
||||
<el-dialog v-model="dialogVisible" :close-on-click-modal="false" :show-close="false" title="错误提示" width="500" :before-close="handleClose">
|
||||
<div style="color: #FF4D4F;font-size: 16px;text-align: center;">原密码验证错误!</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="dialogVisible = false">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -142,6 +148,7 @@ onMounted(() => {
|
||||
border-radius: 4px;
|
||||
box-shadow: 0px 0px 10px rgba(219, 225, 236, 1);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
@ -162,6 +169,7 @@ onMounted(() => {
|
||||
.password-form {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
margin-top: 30px;
|
||||
font-size: 14px;
|
||||
@ -178,6 +186,7 @@ onMounted(() => {
|
||||
color: #363636;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__label) {
|
||||
line-height: 40px !important;
|
||||
}
|
||||
|
||||
@ -34,9 +34,10 @@ function formatTime(dateStr: string): string {
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
||||
}
|
||||
const tableData = computed(() => {
|
||||
const list = state.alarms[state.alarms.length - 1] || {}
|
||||
const arr = []
|
||||
let reslist: any = {}
|
||||
const alarms = state.alarms || []
|
||||
const firstThree = alarms.slice(0, 2)
|
||||
return firstThree.map(list => {
|
||||
const reslist: any = {}
|
||||
if (list.alarm_type == 'line_alarm') {
|
||||
reslist.name = `线路${list?.no || 1}`
|
||||
} else if (list.alarm_type == 'ai_alarm') {
|
||||
@ -48,7 +49,9 @@ const tableData = computed(() => {
|
||||
reslist.content = list.content
|
||||
reslist.time = list.time ? formatTime(list.time) : ''
|
||||
reslist.level = list.level || ''
|
||||
return [reslist]
|
||||
reslist.id = list.id || '0'
|
||||
return reslist
|
||||
})
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
@ -204,7 +207,7 @@ onMounted(() => {
|
||||
|
||||
.container-bottom-box {
|
||||
width: 100%;
|
||||
height: calc(100vh - 660px);
|
||||
height: calc(100vh - 645px);
|
||||
padding: 20px;
|
||||
background: #ffffff;
|
||||
box-shadow: 0px 0px 10px rgba(219, 225, 236, 1);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user