error.response 401的時候登出 | 歷史資料points換成item_name | 告警: 小類預設勾選第一個、告警時間設定新增

This commit is contained in:
koko 2024-12-12 10:28:02 +08:00
parent ccbacf9262
commit b0d0194fe6
7 changed files with 389 additions and 65 deletions

View File

@ -146,7 +146,10 @@
"notify_email": "email",
"notify_items": "通知项目",
"notify_list": "通知名单",
"choose": "选择"
"choose": "选择",
"day_time": "星期/时间",
"click_time_period": "请用滑鼠点击时间段",
"clear": "清空"
},
"operation": {
"title": "运维管理",

View File

@ -146,7 +146,10 @@
"notify_email": "email",
"notify_items": "通知項目",
"notify_list": "通知名單",
"choose": "選擇"
"choose": "選擇",
"day_time":"星期/時間",
"click_time_period":"請用滑鼠點擊時間段",
"clear":"清空"
},
"operation": {
"title": "運維管理",

View File

@ -146,7 +146,10 @@
"notify_email": "Email",
"notify_items": "Notification Items",
"notify_list": "Notification List",
"choose": "Choose"
"choose": "Choose",
"day_time":"Week/Time",
"click_time_period":"Please click the time period with your mouse",
"clear":"Clear"
},
"operation": {
"title": "Operation And Maintenance Management",

View File

@ -38,7 +38,7 @@ instance.interceptors.response.use(
function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
if (response && response.status === 401) {
if (error.response && error.response.status === 401) {
window.location.href = "/logout";
}
return Promise.reject(error);

View File

@ -1,34 +1,236 @@
<script setup>
import { inject, defineProps, watch, ref, provide } from "vue";
import { defineProps, onMounted, onUnmounted, ref, reactive } from "vue";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const props = defineProps({
openModal: Function,
onCancel: Function,
defaultTimeSection: {
type: Object,
default: () => [],
},
});
const closeModal = () => {
props.onCancel();
clear();
};
const columns = [
{
title: "排程名稱",
key: "schedule_name",
},
{
title: "時段",
key: "schedule_time",
},
{
title: "狀態",
key: "enable",
},
{
title: "功能",
key: "operation",
width: 150,
},
];
const tableHeader = ref([
"00",
"01",
"02",
"03",
"04",
"05",
"06",
"07",
"08",
"09",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"20",
"21",
"22",
"23",
]);
const weekDate = ref({
1: "Mon",
2: "Tue",
3: "Wed",
4: "Thu",
5: "Fri",
6: "Sat",
7: "Sun",
});
const rowUnit = ref([]); //
const timeContent = ref([]); //
const timeSection = ref([]); //
const timeStr = ref([]); //
let beginDay = ref(0);
let beginTime = ref(0);
let downEvent = ref(false);
//
const hoverRange = reactive({
startDay: 0,
endDay: 0,
startSlot: 0,
endSlot: 0,
});
const handleMouseMove = (i, day) => {
if (!downEvent.value) return;
hoverRange.startDay = Math.min(beginDay.value, day);
hoverRange.endDay = Math.max(beginDay.value, day);
hoverRange.startSlot = Math.min(beginTime.value, i);
hoverRange.endSlot = Math.max(beginTime.value, i);
};
const initSchedule = () => {
for (let i = 0; i < 7; i++) {
const dayIndex = i + 1;
const defaultTimes = props.defaultTimeSection[dayIndex] || [];
let arr = [];
for (let j = 0; j < 96; j++) {
const timeSlot = j / 4;
const isDefault = defaultTimes.some((timeRange) => {
const [start, end] = timeRange.split("~").map((t) => {
const [hours, minutes] = t.split(":").map(Number);
return hours + minutes / 60;
});
return timeSlot >= start && timeSlot < end;
});
arr.push({ class: isDefault ? "ui-selected" : null, timeData: j });
}
rowUnit.value.push(arr);
timeContent.value.push({
arr: arr
.filter((item) => item.class === "ui-selected")
.map((item) => item.timeData),
});
timeSection.value.push(defaultTimes);
timeStr.value.push(defaultTimes.join(", "));
}
};
const handleMouseDown = (i, day) => {
downEvent.value = true; //
beginDay.value = day;
beginTime.value = i;
};
const handleMouseUp = (i, day) => {
let begin = beginTime.value;
let start = begin <= i ? begin : i; //x
let length = Math.abs(begin - i);
let end = start + length; //x
let dayStart = beginDay.value <= day ? beginDay.value : day; //y
let dayLength = Math.abs(beginDay.value - day);
let dayEnd = dayStart + dayLength; //y
const isAdd = () => {
//,
for (let x = dayStart; x < dayEnd + 1; x++) {
for (let y = start; y < end + 1; y++) {
if (rowUnit.value[x][y].class === null) return true;
}
}
return false;
};
if (downEvent.value) {
//table
if (isAdd()) {
for (let x = dayStart; x < dayEnd + 1; x++) {
for (let y = start; y < end + 1; y++) {
if (rowUnit.value[x][y].class === null) {
rowUnit.value[x][y].class = "ui-selected";
timeContent.value[x].arr.push(rowUnit.value[x][y].timeData);
}
}
}
} else {
for (let x = dayStart; x < dayEnd + 1; x++) {
for (let y = start; y < end + 1; y++) {
if (rowUnit.value[x][y].class === "ui-selected") {
rowUnit.value[x][y].class = null;
let c = rowUnit.value[x][y].timeData;
let kong = "";
for (let i = 0; i < timeContent.value[x].arr.length; i++) {
if (c === timeContent.value[x].arr[i]) {
kong = i;
}
}
timeContent.value[x].arr.splice(kong, 1);
}
}
}
}
//,
filterTime(dayStart, dayEnd);
}
downEvent.value = false;
hoverRange.startDay = hoverRange.endDay = 0;
hoverRange.startSlot = hoverRange.endSlot = 0;
};
const filterTime = (start, end) => {
const toStr = (num) => {
if (Number.isInteger(num)) {
return `${num < 10 ? "0" + num : num}:00`;
} else {
const intPart = Math.floor(num);
const fracPart = num - intPart;
const str = intPart < 10 ? "0" + intPart : intPart.toString();
return `${str}:${
fracPart === 0.25 ? "15" : fracPart === 0.5 ? "30" : "45"
}`;
}
};
const timeToStr = (arr) => {
return arr.map(([start, end]) => `${toStr(start)}~${toStr(end)}`);
};
for (let i = start; i <= end; i++) {
const sortedArr = [...new Set(timeContent.value[i].arr)].sort(
(a, b) => a - b
);
const sections = [];
for (let j = 0; j < sortedArr.length; j++) {
if (j === 0 || sortedArr[j] !== sortedArr[j - 1] + 1) {
sections.push([sortedArr[j], sortedArr[j]]);
} else {
sections[sections.length - 1][1] = sortedArr[j];
}
}
timeSection.value[i] = timeToStr(
sections.map(([start, end]) => [start / 4, (end + 1) / 4])
);
timeStr.value[i] = timeSection.value[i].join(", ");
}
};
const clear = () => {
rowUnit.value.forEach((item) => {
item.forEach((item1) => {
item1.class = null;
});
});
timeContent.value.forEach((item) => {
item.arr = [];
});
timeSection.value.forEach((item) => {
item.length = 0;
});
timeStr.value.length = 0;
for (let i = 0; i < 7; i++) {
timeStr.value.push("");
}
};
const onOk = async () => {};
onMounted(() => {
initSchedule();
});
</script>
<template>
@ -36,10 +238,10 @@ const columns = [
id="outliers_time_item"
:open="open"
:onCancel="closeModal"
width="800"
width="1400"
>
<template #modalTitle>
<p>警示時間設定</p>
<p>{{ $t("alert.warning_time") }}</p>
<button class="fixed right-10 top-5" @click.prevent="closeModal">
<font-awesome-icon
:icon="['fas', 'times']"
@ -49,34 +251,144 @@ const columns = [
</button>
</template>
<template #modalContent>
<Table
:columns="columns"
:dataSource="tableData"
class="mt-3"
:withStyle="false"
<div class="weektime mt-5">
<div class="calendar">
<table class="calendar-table w-full">
<thead class="calendar-head">
<tr>
<th rowspan="6" class="w-20 py-4">
{{ $t("alert.day_time") }}
</th>
<th colspan="48">00:00 - 12:00</th>
<th colspan="48">12:00 - 24:00</th>
</tr>
<tr>
<td
colspan="4"
v-for="(item, index) in tableHeader"
:key="index"
>
<template #bodyCell="{ record, column, index }">
<template v-if="column.key === 'operation'">
{{ item }}
</td>
</tr>
</thead>
<tbody id="tableBody">
<tr v-for="(day, index) in weekDate" :key="index">
<td>{{ day }}</td>
<td
v-for="(item, i) in rowUnit[index - 1]"
:key="i"
@mousedown.prevent="handleMouseDown(i, index - 1)"
@mouseup.prevent="handleMouseUp(i, index - 1)"
@mousemove.prevent="handleMouseMove(i, index - 1)"
class="calendar-atom-time"
:class="{
'ui-selected': item.class === 'ui-selected',
'hover-highlight':
downEvent &&
index - 1 >= hoverRange.startDay &&
index - 1 <= hoverRange.endDay &&
i >= hoverRange.startSlot &&
i <= hoverRange.endSlot,
}"
></td>
</tr>
<tr>
<td colspan="97" class="py-2">
<span class="text-base">{{
$t("alert.click_time_period")
}}</span>
<a
@click="clear"
class="cursor-pointer text-active text-base"
>
{{ $t("alert.clear") }}
</a>
</td>
</tr>
<tr>
<td colspan="97" class="timeContent">
<div
v-for="(item, index) in timeStr"
:key="index"
v-show="item.length"
>
<span>{{ weekDate[index + 1] }}: </span>
<strong>
<span>{{ item }}</span>
</strong>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<template #modalAction>
<button
class="btn btn-sm btn-success text-white mr-2"
@click.stop.prevent="() => openModal(record)"
type="reset"
class="btn btn-outline-success mr-2"
@click.prevent="closeModal"
>
修改
{{ $t("button.cancel") }}
</button>
<button
class="btn btn-sm btn-error text-white"
@click.stop.prevent="() => remove(record.userinfo_guid)"
type="submit"
class="btn btn-outline-success"
@click.prevent="onOk"
>
刪除
{{ $t("button.submit") }}
</button>
</template>
<template v-else>
{{ record[column.key] }}
</template>
</template>
</Table>
</template>
</Modal>
</template>
<style lang="scss" scoped></style>
<style lang="css" scoped>
.weektime .calendar {
-webkit-user-select: none;
position: relative;
display: inline-block;
width: 100%;
}
.weektime .calendar .calendar-table tr .calendar-atom-time:hover {
background: #ccc;
}
.weektime .calendar .calendar-table tr .ui-selected {
background: #00ffb3;
}
.weektime .calendar .calendar-table tr .ui-selected:hover {
background: #ccc;
}
.weektime .calendar .calendar-table tr,
.weektime .calendar .calendar-table td,
.weektime .calendar .calendar-table th {
border: 1px solid #ccc;
font-size: 13px;
text-align: center;
line-height: 1.8em;
transition: background 200ms ease;
}
.weektime .calendar .calendar-table tbody tr {
height: 35px;
}
.weektime .calendar .calendar-table tbody tr td:first-child {
background: #123;
}
.weektime .calendar .calendar-table thead th,
.weektime .calendar .calendar-table thead td {
background: #123;
}
.hover-highlight {
background: rgba(0, 255, 145, 0.5); /* 淡藍色透明背景 */
border: 1px dashed #00ffb3; /* 藍色虛線邊框 */
}
</style>

View File

@ -9,15 +9,18 @@ const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
const getSubSystems = async () => {
const res = await getAlertSubList();
const subSystems = res.data.history_Main_Systems.flatMap((mainSystem) => {
return mainSystem.history_Sub_systems.map((subSystem, index) => ({
const history_Sub_systems = res.data.history_Main_Systems.flatMap(
(mainSystem) => {
return mainSystem.history_Sub_systems;
}
);
const subSystems = history_Sub_systems.map((subSystem, index) => ({
title: subSystem.full_name,
key: subSystem.sub_system_tag,
active: searchParams.value?.subSys_id
? searchParams.value.subSys_id === subSystem.sub_system_tag
: index == 0,
}));
});
setItems(subSystems);
};

View File

@ -19,7 +19,7 @@ const columns = computed(() => [
},
{
title: t("history.category"),
key: "points",
key: "item_name",
},
{
title: t("history.value"),