init
4
.env.development
Normal file
@ -0,0 +1,4 @@
|
||||
VITE_API_BASEURL = "https://ibms-Empower-api.production.mjmtech.com.tw"
|
||||
VITE_FILE_API_BASEURL = "https://ibms-Empower.production.mjmtech.com.tw"
|
||||
VITE_MQTT_BASEURL = "wss://mqttwss.mjm-staging.developers-homelab.net"
|
||||
VITE_FORGE_BASEURL = "https://ibms-Empower.production.mjmtech.com.tw/dist"
|
4
.env.production
Normal file
@ -0,0 +1,4 @@
|
||||
VITE_API_BASEURL = "https://ibms-Empower-api.production.mjmtech.com.tw"
|
||||
VITE_FILE_API_BASEURL = "https://ibms-Empower.production.mjmtech.com.tw"
|
||||
VITE_MQTT_BASEURL = "wss://mqttwss.mjm-staging.developers-homelab.net"
|
||||
VITE_FORGE_BASEURL = "https://ibms-Empower.production.mjmtech.com.tw/dist"
|
3
.env.staging
Normal file
@ -0,0 +1,3 @@
|
||||
VITE_API_BASEURL = "http://220.132.206.5:8008"
|
||||
VITE_FILE_API_BASEURL = "http://220.132.206.5:8085/file"
|
||||
VITE_FORGE_BASEURL = "http://localhost:5173"
|
24
.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
26
index.html
Normal file
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- @noSnoop -->
|
||||
<html lang="en" data-theme="dracula">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.css"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>新創賦能</title>
|
||||
<script src="https://code.jquery.com/jquery-3.7.1.js"></script>
|
||||
<script src="https://code.jquery.com/ui/1.13.3/jquery-ui.js"></script>
|
||||
<!-- <script type="text/javascript" src="/requirejs/config.js"></script> -->
|
||||
<!-- <script
|
||||
type="text/javascript"
|
||||
src="/module/js/com/tridium/js/ext/require/require.min.js?"
|
||||
></script> -->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.js"></script>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
6457
package-lock.json
generated
Normal file
51
package.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "ibms_netzero",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"homepage": "/netzero",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.36",
|
||||
"@fortawesome/free-brands-svg-icons": "^5.15.4",
|
||||
"@fortawesome/free-regular-svg-icons": "^5.15.4",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.15.4",
|
||||
"@fortawesome/vue-fontawesome": "^3.0.5",
|
||||
"@vuepic/vue-datepicker": "^8.0.0",
|
||||
"ant-design-vue": "^4.0.7",
|
||||
"axios": "^1.6.2",
|
||||
"date-fns": "^3.3.1",
|
||||
"dayjs": "^1.11.10",
|
||||
"echarts": "^5.4.3",
|
||||
"flag-icons": "^7.2.3",
|
||||
"jquery-ui": "^1.14.1",
|
||||
"json-schema-generator": "^2.0.6",
|
||||
"mqtt": "^5.10.3",
|
||||
"pinia": "^2.1.7",
|
||||
"requirejs": "^2.3.6",
|
||||
"tailwind-merge": "^2.2.1",
|
||||
"vue": "^3.3.4",
|
||||
"vue-i18n": "^10.0.4",
|
||||
"vue-router": "^4.2.5",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"yup": "^1.4.0",
|
||||
"yup-phone-lite": "^2.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^9.7.0",
|
||||
"@vitejs/plugin-vue": "^4.4.0",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"daisyui": "^4.4.17",
|
||||
"postcss": "^8.4.31",
|
||||
"sass": "^1.69.5",
|
||||
"sass-loader": "^13.3.2",
|
||||
"tailwindcss": "^3.3.5",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^4.4.11",
|
||||
"vite-plugin-svg-icons": "^2.0.1"
|
||||
}
|
||||
}
|
7
postcss.config.js
Normal file
@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
"postcss-import": {},
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
BIN
public/build_img.jpg
Normal file
After Width: | Height: | Size: 137 KiB |
44
public/config.json
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"heatmap": {
|
||||
"temp": {
|
||||
"range": [0, 50],
|
||||
"color": ["#0023F5", "#FF1C05"],
|
||||
"unit": "°C"
|
||||
},
|
||||
"humi": {
|
||||
"range": [15, 95],
|
||||
"color": ["#ADD8E6", "#00008B"],
|
||||
"unit": "%"
|
||||
},
|
||||
"CO2": {
|
||||
"range": [0, 5000],
|
||||
"color": ["#FFDAB9", "#FF8C00"],
|
||||
"unit": "ppm"
|
||||
},
|
||||
"CO": {
|
||||
"range": [0, 1000],
|
||||
"color": ["#FFFFE0", "#FFD700"],
|
||||
"unit": "ppm"
|
||||
},
|
||||
"CH2O": {
|
||||
"range": [0, 100],
|
||||
"color": ["#90EE90", "#006400"],
|
||||
"unit": "ppb"
|
||||
},
|
||||
"PM1": {
|
||||
"range": [0, 20],
|
||||
"color": ["#E6E6FA", "#800080"],
|
||||
"unit": "µg/m³"
|
||||
},
|
||||
"PM2.5": {
|
||||
"range": [0, 55],
|
||||
"color": ["#FFB6C1", "#FF0000"],
|
||||
"unit": "µg/m³"
|
||||
},
|
||||
"PM10": {
|
||||
"range": [0, 150],
|
||||
"color": ["#FFDDC1", "#FF1493"],
|
||||
"unit": "µg/m³"
|
||||
}
|
||||
}
|
||||
}
|
BIN
public/favicon.ico
Normal file
After Width: | Height: | Size: 2.8 KiB |
21
public/hotspot.svg
Normal file
@ -0,0 +1,21 @@
|
||||
<svg width="164" height="164" viewBox="0 0 164 164" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<g>
|
||||
<circle cx="81.7363" cy="81.8212" r="40" stroke-width="60" style="stroke:grey" />
|
||||
</g>
|
||||
<g filter="url(#filter0_d)">
|
||||
<circle cx="81.7363" cy="81.8212" r="20" stroke="white" stroke-width="60"/>
|
||||
</g>
|
||||
|
||||
<defs>
|
||||
<filter id="filter0_d" x="0.174763" y="0.259602" width="163.123" height="163.123" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="5.61135"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 938 B |
23
public/logo.svg
Normal file
After Width: | Height: | Size: 34 KiB |
15
public/setting.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
window.addEventListener("load", () => {
|
||||
window.location.href = "/file/dist/index.html";
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
60
src/App.vue
Normal file
@ -0,0 +1,60 @@
|
||||
<script setup>
|
||||
import { RouterView } from "vue-router";
|
||||
import Navbar from "./components/navbar/Navbar.vue";
|
||||
import useUserInfoStore from "@/stores/useUserInfoStore";
|
||||
import { ref, provide, onUnmounted, onMounted } from "vue";
|
||||
|
||||
const store = useUserInfoStore();
|
||||
let isToastOpen = ref({
|
||||
open: false,
|
||||
content: "",
|
||||
status: "info",
|
||||
to: "body",
|
||||
});
|
||||
const cancelToastOpen = () => {
|
||||
isToastOpen.value = {
|
||||
open: false,
|
||||
content: "",
|
||||
};
|
||||
};
|
||||
|
||||
const openToast = (status, content, to = "body", confirm = null) => {
|
||||
isToastOpen.value = {
|
||||
open: true,
|
||||
content,
|
||||
status,
|
||||
to,
|
||||
confirm,
|
||||
};
|
||||
};
|
||||
provide("app_toast", { openToast, cancelToastOpen });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Toast
|
||||
:content="isToastOpen.content"
|
||||
:open="isToastOpen.open"
|
||||
:status="isToastOpen.status"
|
||||
:cancel="cancelToastOpen"
|
||||
:confirm="isToastOpen.confirm"
|
||||
:to="isToastOpen.to"
|
||||
/>
|
||||
<div v-if="store.user.token" class="min-h-screen">
|
||||
<Navbar />
|
||||
<div class="px-3 lg:px-8 w-full relative app-container " style="min-height: calc(100vh - 6rem);">
|
||||
<RouterView />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="min-h-screen"><RouterView /></div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
header {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: block;
|
||||
margin: 0 auto 1rem;
|
||||
}
|
||||
</style>
|
14
src/apis/account/api.js
Normal file
@ -0,0 +1,14 @@
|
||||
export const GET_ACCOUNT_USERLIST_API = `/User/UserManagerList`;
|
||||
|
||||
export const GET_ACCOUNT_ROLELIST_API = `/User/RoleManagerList`;
|
||||
export const GET_ACCOUNT_ROLEAUTHLIST_API = `/User/RoleAuthList`;
|
||||
export const GET_ACCOUNT_ROLEAUTHPAGELIST_API = `/User/AuthPageListByVariable`;
|
||||
|
||||
// export const POST_ROLEAUTHLIST_API = `/User/SaveRoleAuth`;
|
||||
|
||||
export const POST_ACCOUNT_ROLE_API = `/User/SaveRoleAndAuth`;
|
||||
export const DELETE_ACCOUNT_ROLE_API = `/User/DeleteOneRole`;
|
||||
|
||||
export const GET_ACCOUNT_USER_API = `/User/GetOneUser`;
|
||||
export const POST_ACCOUNT_USER_API = `/User/SaveUser`;
|
||||
export const DELETE_ACCOUNT_USER_API = `/User/DeleteOneUser`;
|
158
src/apis/account/index.js
Normal file
@ -0,0 +1,158 @@
|
||||
import {
|
||||
GET_ACCOUNT_USERLIST_API,
|
||||
GET_ACCOUNT_ROLELIST_API,
|
||||
GET_ACCOUNT_ROLEAUTHLIST_API,
|
||||
GET_ACCOUNT_ROLEAUTHPAGELIST_API,
|
||||
DELETE_ACCOUNT_ROLE_API,
|
||||
POST_ACCOUNT_ROLE_API,
|
||||
POST_ACCOUNT_USER_API,
|
||||
GET_ACCOUNT_USER_API,
|
||||
DELETE_ACCOUNT_USER_API,
|
||||
} from "./api";
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
|
||||
export const getAccountUserList = async (search_condition = {}) => {
|
||||
const res = await instance.post(GET_ACCOUNT_USERLIST_API, search_condition);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAccountRoleList = async (search_condition = {}) => {
|
||||
const res = await instance.post(GET_ACCOUNT_ROLELIST_API, {
|
||||
Layer: 1,
|
||||
...search_condition,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAccountRoleAuthList = async (SelectedRoleId) => {
|
||||
const res = await instance.post(GET_ACCOUNT_ROLEAUTHLIST_API, {
|
||||
SelectedRoleId,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAccountRoleAuthPageList = async () => {
|
||||
const res = await instance.post(GET_ACCOUNT_ROLEAUTHPAGELIST_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postAccountRole = async ({ Id, Name, SaveCheckAuth }) => {
|
||||
const res = await instance.post(POST_ACCOUNT_ROLE_API, {
|
||||
Id,
|
||||
Name,
|
||||
SaveCheckAuth,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const delRole = async (Id) => {
|
||||
const res = await instance.post(DELETE_ACCOUNT_ROLE_API, {
|
||||
Id,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAccountOneUser = async (Id) => {
|
||||
const res = await instance.post(GET_ACCOUNT_USER_API, {
|
||||
Id,
|
||||
});
|
||||
|
||||
res.data = {
|
||||
Account: res.data?.account,
|
||||
Name: res.data?.full_name,
|
||||
Email: res.data?.email,
|
||||
Phone: res.data?.phone,
|
||||
RoleId: res.data?.role_guid,
|
||||
Id,
|
||||
};
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postAccountUser = async ({
|
||||
Id,
|
||||
Account,
|
||||
Name,
|
||||
Email,
|
||||
Phone,
|
||||
RoleId,
|
||||
Password,
|
||||
}) => {
|
||||
const res = await instance.post(
|
||||
POST_ACCOUNT_USER_API,
|
||||
Id
|
||||
? {
|
||||
Id: Id,
|
||||
Account,
|
||||
Name,
|
||||
Email,
|
||||
Phone,
|
||||
RoleId,
|
||||
}
|
||||
: {
|
||||
Id: "0",
|
||||
Account,
|
||||
Name,
|
||||
Email,
|
||||
Phone,
|
||||
RoleId,
|
||||
Password,
|
||||
}
|
||||
);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const changePassword = async ({ Id, Password }) => {
|
||||
const res = await instance.post(POST_ACCOUNT_USER_API, {
|
||||
Id,
|
||||
Password,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const delAccount = async (Id) => {
|
||||
const res = await instance.post(DELETE_ACCOUNT_USER_API, {
|
||||
Id,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
26
src/apis/alert/api.js
Normal file
@ -0,0 +1,26 @@
|
||||
export const POST_ACK_API = `/obix/alarm`;
|
||||
export const GET_ALERT_FORMID_API = `/Alert/AlertList`;
|
||||
export const GET_ALERT_LOG_API = `api/Alarm/GetAlarmLog`;
|
||||
export const POST_OPERATION_RECORD_API = `/operation/SavOpeRecord`;
|
||||
|
||||
export const GET_ALERT_SUB_LIST_API = `api/Device/GetMainSub`;
|
||||
|
||||
export const GET_ALERT_MEMBER_LIST_API = `api/Alarm/GetAlarmMemberList`;
|
||||
export const GET_ALERT_MEMBER = `api/Alarm/GetAlarmMember`;
|
||||
export const POST_ALERT_MEMBER = `api/Alarm/SaveAlarmMember`;
|
||||
export const DELETE_ALERT_MEMBER = `api/Alarm/DeleteAlarmMember`;
|
||||
export const GET_NOTICE_LIST_API = `api/Alarm/GetNotice`;
|
||||
export const GET_SHOW_ALERT_API = `api/Alarm/GetShowAlarm`; // 取得告警顯示清單
|
||||
|
||||
export const GET_OUTLIERS_LIST_API = `api/Alarm/GetAlarmSetting`;
|
||||
export const GET_OUTLIERS_DEVLIST_API = `api/Alarm/GetDevList`; // 取得設備
|
||||
export const GET_OUTLIERS_POINTS_API = `api/Alarm/GetAlarmPoints`; // 取得點位
|
||||
export const POST_OUTLIERS_SETTING_API = `api/Alarm/SaveAlarmSetting`; // 新增與修改
|
||||
export const DELETE_OUTLIERS_SETTING_API = `api/Alarm/DeleteAlarmSetting`; // 刪除
|
||||
export const GET_FACTOR_API = `api/Alarm/GetFactor`; // 刪除
|
||||
|
||||
export const GET_ALERT_SCHEDULE_LIST_API = `api/Alarm/GetAlarmSchedule`;
|
||||
export const POST_ALERT_SCHEDULE = `api/Alarm/SaveAlarmSchedule`;
|
||||
export const DELETE_ALERT_SCHEDULE = `api/Alarm/DeleteAlarmSchedule`;
|
||||
|
||||
export const POST_ALERT_MQTT_REFRESH = `api/Alarm/MQTTRefresh`;
|
227
src/apis/alert/index.js
Normal file
@ -0,0 +1,227 @@
|
||||
import {
|
||||
POST_ACK_API,
|
||||
GET_ALERT_FORMID_API,
|
||||
GET_ALERT_LOG_API,
|
||||
POST_OPERATION_RECORD_API,
|
||||
GET_ALERT_SUB_LIST_API,
|
||||
GET_OUTLIERS_LIST_API,
|
||||
GET_OUTLIERS_DEVLIST_API,
|
||||
GET_OUTLIERS_POINTS_API,
|
||||
POST_OUTLIERS_SETTING_API,
|
||||
DELETE_OUTLIERS_SETTING_API,
|
||||
GET_FACTOR_API,
|
||||
GET_ALERT_MEMBER_LIST_API,
|
||||
GET_ALERT_MEMBER,
|
||||
POST_ALERT_MEMBER,
|
||||
DELETE_ALERT_MEMBER,
|
||||
GET_NOTICE_LIST_API,
|
||||
GET_SHOW_ALERT_API,
|
||||
GET_ALERT_SCHEDULE_LIST_API,
|
||||
POST_ALERT_SCHEDULE,
|
||||
DELETE_ALERT_SCHEDULE,
|
||||
POST_ALERT_MQTT_REFRESH
|
||||
} from "./api";
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
|
||||
export const getAlertFormId = async (uuid) => {
|
||||
const res = await instance.post(GET_ALERT_FORMID_API, uuid);
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAlertLog = async ({
|
||||
Start_date,
|
||||
End_date,
|
||||
isRecovery,
|
||||
device_name_tag,
|
||||
}) => {
|
||||
const res = await instance.post(GET_ALERT_LOG_API, {
|
||||
Start_date,
|
||||
End_date,
|
||||
isRecovery,
|
||||
device_name_tag,
|
||||
});
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postOperationRecord = async (formData) => {
|
||||
const res = await instance.post(POST_OPERATION_RECORD_API, formData);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAlertSubList = async (building_guid) => {
|
||||
const res = await instance.post(GET_ALERT_SUB_LIST_API, {
|
||||
building_guid,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAlarmMemberList = async () => {
|
||||
const res = await instance.post(GET_ALERT_MEMBER_LIST_API, {});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getNoticeList = async (lang) => {
|
||||
const res = await instance.post(GET_NOTICE_LIST_API, { lang });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postAlertMember = async (data) => {
|
||||
const res = await instance.post(POST_ALERT_MEMBER, data);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteAlarmMember = async (id) => {
|
||||
try {
|
||||
const res = await instance.post(DELETE_ALERT_MEMBER, { id });
|
||||
console.log("Delete Alarm Member Response:", res);
|
||||
return {
|
||||
isSuccess: res.code === "0000",
|
||||
msg: res.msg || "刪除成功",
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("API request failed", error);
|
||||
return { isSuccess: false, msg: "API request failed" };
|
||||
}
|
||||
};
|
||||
|
||||
export const getAlarmMember = async (data) => {
|
||||
try {
|
||||
const res = await instance.post(GET_ALERT_MEMBER, data);
|
||||
return res.data;
|
||||
} catch (error) {
|
||||
console.error("API request failed", error);
|
||||
return { isSuccess: false, msg: "API request failed" };
|
||||
}
|
||||
};
|
||||
|
||||
export const getOutliersList = async (id) => {
|
||||
const res = await instance.post(GET_OUTLIERS_LIST_API, id);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getOutliersDevList = async (id) => {
|
||||
const res = await instance.post(GET_OUTLIERS_DEVLIST_API, id);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getOutliersPoints = async (id) => {
|
||||
const res = await instance.post(GET_OUTLIERS_POINTS_API, id);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getFactors = async () => {
|
||||
const res = await instance.post(GET_FACTOR_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postOutliersSetting = async (data) => {
|
||||
const res = await instance.post(POST_OUTLIERS_SETTING_API, data);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const delOutliersSetting = async (Id) => {
|
||||
const res = await instance.post(DELETE_OUTLIERS_SETTING_API, {
|
||||
Id,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getShowAlarm = async () => {
|
||||
const res = await instance.post(GET_SHOW_ALERT_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAlarmScheduleList = async () => {
|
||||
const res = await instance.post(GET_ALERT_SCHEDULE_LIST_API, {});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postAlertSchedule = async (data) => {
|
||||
const res = await instance.post(POST_ALERT_SCHEDULE, data);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteAlarmSchedule = async (id) => {
|
||||
try {
|
||||
const res = await instance.post(DELETE_ALERT_SCHEDULE, { id });
|
||||
return {
|
||||
isSuccess: res.code === "0000",
|
||||
msg: res.msg || "刪除成功",
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("API request failed", error);
|
||||
return { isSuccess: false, msg: "API request failed" };
|
||||
}
|
||||
};
|
||||
|
||||
export const postMQTTRefresh = async () => {
|
||||
const res = await instance.post(POST_ALERT_MQTT_REFRESH);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
37
src/apis/asset/api.js
Normal file
@ -0,0 +1,37 @@
|
||||
export const GET_ASSET_MAIN_LIST_API = `/AssetManage/GetAssetMainList`;
|
||||
export const DELETE_ASSET_MAIN_LIST_API = `/AssetManage/DeleteAssetMain`;
|
||||
export const POST_ASSET_MAIN_LIST_API = `/AssetManage/SaveAssetMain`;
|
||||
|
||||
export const GET_ASSET_SUB_LIST_API = `/AssetManage/GetAssetSubList`;
|
||||
export const POST_ASSET_SUB_LIST_API = `/AssetManage/SaveAssetSub`;
|
||||
export const DELETE_ASSET_SUB_LIST_API = `/AssetManage/DeleteAssetSub`;
|
||||
|
||||
export const GET_ASSET_LIST_API = `/AssetManage/GetAssetList`;
|
||||
export const GET_ASSET_SINGLE_API = `/AssetManage/GetAsset`;
|
||||
export const POST_ASSET_SINGLE_API = `/AssetManage/SaveAsset`;
|
||||
export const DELETE_ASSET_ITEM_API = `/AssetManage/DeleteAsset`;
|
||||
|
||||
export const GET_ASSET_FLOOR_LIST_API = `/AssetManage/GetFloorList`;
|
||||
|
||||
export const POST_ASSET_FLOOR_API = `/AssetManage/SaveFloor`;
|
||||
export const DELETE_ASSET_FLOOR_API = `/AssetManage/DeleteFloor`;
|
||||
|
||||
export const GET_ASSET_IOT_LIST_API = `/AssetManage/GetIOTList`;
|
||||
export const GET_ASSET_SUB_POINT_API = `/AssetManage/GetSubPoint`;
|
||||
|
||||
export const GET_ASSET_IOT_SCHEMA_API = `/AssetManage/GetResponseSchema`;
|
||||
export const POST_ASSET_IOT_SCHEMA_API = `/AssetManage/SaveResponseSchema`;
|
||||
|
||||
export const GET_ASSET_DEVICE_ITEM_API = `/AssetManage/GetDeviceItem`;
|
||||
export const POST_ASSET_DEVICE_ITEM_API = `/AssetManage/SaveDeviceItem`;
|
||||
export const DELETE_ASSET_DEVICE_ITEM_API = `/AssetManage/DeleteDeviceItem`;
|
||||
|
||||
export const GET_ASSET_DEPARTMENT_API = `/AssetManage/GetDepartment`;
|
||||
export const POST_ASSET_DEPARTMENT_API = `/AssetManage/SaveDepartment`;
|
||||
export const DELETE_ASSET_DEPARTMENT_API = `/AssetManage/DeleteDepartment`;
|
||||
|
||||
export const GET_ASSET_ELECTYPE_API = `/AssetManage/GetElecType`;
|
||||
export const POST_ASSET_ELECTYPE_API = `/AssetManage/SaveElecType`;
|
||||
export const DELETE_ASSET_ELECTYPE_API = `/AssetManage/DeleteElecType`;
|
||||
|
||||
export const POST_ASSET_ELEC_SETTING_API = `/AssetManage/SaveAssetSetting`;
|
337
src/apis/asset/index.js
Normal file
@ -0,0 +1,337 @@
|
||||
import {
|
||||
GET_ASSET_MAIN_LIST_API,
|
||||
DELETE_ASSET_MAIN_LIST_API,
|
||||
POST_ASSET_MAIN_LIST_API,
|
||||
GET_ASSET_SUB_LIST_API,
|
||||
DELETE_ASSET_SUB_LIST_API,
|
||||
POST_ASSET_SUB_LIST_API,
|
||||
GET_ASSET_LIST_API,
|
||||
GET_ASSET_SINGLE_API,
|
||||
GET_ASSET_FLOOR_LIST_API,
|
||||
POST_ASSET_FLOOR_API,
|
||||
DELETE_ASSET_FLOOR_API,
|
||||
GET_ASSET_IOT_LIST_API,
|
||||
DELETE_ASSET_ITEM_API,
|
||||
POST_ASSET_SINGLE_API,
|
||||
GET_ASSET_SUB_POINT_API,
|
||||
GET_ASSET_IOT_SCHEMA_API,
|
||||
POST_ASSET_IOT_SCHEMA_API,
|
||||
GET_ASSET_DEVICE_ITEM_API,
|
||||
POST_ASSET_DEVICE_ITEM_API,
|
||||
DELETE_ASSET_DEVICE_ITEM_API,
|
||||
GET_ASSET_DEPARTMENT_API,
|
||||
POST_ASSET_DEPARTMENT_API,
|
||||
DELETE_ASSET_DEPARTMENT_API,
|
||||
GET_ASSET_ELECTYPE_API,
|
||||
POST_ASSET_ELECTYPE_API,
|
||||
DELETE_ASSET_ELECTYPE_API,
|
||||
POST_ASSET_ELEC_SETTING_API,
|
||||
} from "./api";
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
import { object } from "yup";
|
||||
|
||||
export const getAssetMainList = async (building_guid) => {
|
||||
const res = await instance.post(GET_ASSET_MAIN_LIST_API,{building_guid});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteAssetMainItem = async (id) => {
|
||||
const res = await instance.post(DELETE_ASSET_MAIN_LIST_API, { id });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postAssetMainList = async ({ id, system_key, system_value, building_guid }) => {
|
||||
const res = await instance.post(POST_ASSET_MAIN_LIST_API, {
|
||||
id,
|
||||
system_key,
|
||||
system_value,
|
||||
building_guid
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAssetSubList = async (id) => {
|
||||
const res = await instance.post(GET_ASSET_SUB_LIST_API, { id });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postAssetSubList = async (formData) => {
|
||||
const res = await instance.post(POST_ASSET_SUB_LIST_API, formData);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteAssetSubItem = async (id) => {
|
||||
const res = await instance.post(DELETE_ASSET_SUB_LIST_API, { id });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAssetList = async (variable_id) => {
|
||||
const res = await instance.post(GET_ASSET_LIST_API, {
|
||||
variable_id: parseInt(variable_id),
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAssetSingle = async (main_id) => {
|
||||
const res = await instance.post(GET_ASSET_SINGLE_API, { main_id });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postAssetSingle = async (data) => {
|
||||
let formData = new FormData();
|
||||
|
||||
for (let [key, value] of Object.entries(data)) {
|
||||
console.log(key, value);
|
||||
if (Array.isArray(value)) {
|
||||
if (key === "oriFile") {
|
||||
value.forEach((element, index) => {
|
||||
formData.append(`${key}[${index}].file`, element.id ? null : element);
|
||||
formData.append(`${key}[${index}].orgName`, element.name);
|
||||
formData.append(
|
||||
`${key}[${index}].saveName`,
|
||||
element.id ? element.saveName : ""
|
||||
);
|
||||
});
|
||||
} else {
|
||||
value.forEach((element, index) => {
|
||||
formData.append(
|
||||
`sub_device[${index}].device_number`,
|
||||
element.device_number
|
||||
);
|
||||
formData.append(`sub_device[${index}].points`, element.points);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
formData.append(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
const res = await instance.post(POST_ASSET_SINGLE_API, formData);
|
||||
return apihandler(res.code, res.data, { msg: res.msg, code: res.code });
|
||||
};
|
||||
|
||||
export const deleteAssetItem = async (main_id) => {
|
||||
const res = await instance.post(DELETE_ASSET_ITEM_API, { main_id });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAssetFloorList = async (building_guid) => {
|
||||
const res = await instance.post(GET_ASSET_FLOOR_LIST_API, { building_guid });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postAssetFloor = async (formData) => {
|
||||
const res = await instance.post(POST_ASSET_FLOOR_API, formData);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteAssetFloor = async (formData) => {
|
||||
const res = await instance.post(DELETE_ASSET_FLOOR_API, formData);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAssetIOTList = async (sub_system_tag, points) => {
|
||||
const res = await instance.post(GET_ASSET_IOT_LIST_API, {
|
||||
sub_system_tag,
|
||||
points,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAssetSubPoint = async (sub_system_tag) => {
|
||||
const res = await instance.post(GET_ASSET_SUB_POINT_API, {
|
||||
sub_system_tag,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getIOTSchema = async (variable_id) => {
|
||||
const res = await instance.post(GET_ASSET_IOT_SCHEMA_API, { variable_id });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postIOTSchema = async ({ name, variable_id, points }) => {
|
||||
const res = await instance.post(POST_ASSET_IOT_SCHEMA_API, {
|
||||
name,
|
||||
variable_id,
|
||||
points,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getDeviceItem = async (variable_id) => {
|
||||
const res = await instance.post(GET_ASSET_DEVICE_ITEM_API, { variable_id });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postDeviceItem = async ({
|
||||
id,
|
||||
variable_id,
|
||||
full_name,
|
||||
points,
|
||||
decimals,
|
||||
is_bool,
|
||||
is_link,
|
||||
}) => {
|
||||
const res = await instance.post(POST_ASSET_DEVICE_ITEM_API, {
|
||||
id,
|
||||
variable_id,
|
||||
full_name,
|
||||
points,
|
||||
decimals,
|
||||
is_bool,
|
||||
is_link,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteDeviceItem = async (id) => {
|
||||
const res = await instance.post(DELETE_ASSET_DEVICE_ITEM_API, { id });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getDepartmentList = async () => {
|
||||
const res = await instance.post(GET_ASSET_DEPARTMENT_API, {});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postDepartmentList = async ({ name, id }) => {
|
||||
const res = await instance.post(POST_ASSET_DEPARTMENT_API, {
|
||||
name,
|
||||
id,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteDepartmentItem = async (id) => {
|
||||
const res = await instance.post(DELETE_ASSET_DEPARTMENT_API, { id });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getElecTypeList = async () => {
|
||||
const res = await instance.post(GET_ASSET_ELECTYPE_API, {});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postElecTypeList = async ({ name, id }) => {
|
||||
const res = await instance.post(POST_ASSET_ELECTYPE_API, {
|
||||
name,
|
||||
id,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteElecTypeItem = async (id) => {
|
||||
const res = await instance.post(DELETE_ASSET_ELECTYPE_API, { id });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postAssetElecSetting = async (formData) => {
|
||||
const res = await instance.post(POST_ASSET_ELEC_SETTING_API, formData);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
6
src/apis/building/api.js
Normal file
@ -0,0 +1,6 @@
|
||||
export const GET_BUILDING_API = `/AssetManage/GetBuildingList`;
|
||||
export const POST_BUILDING_API = `/AssetManage/SaveBuilding`;
|
||||
export const DELETE_BUILDING_API = `/AssetManage/DeleteBuilding`;
|
||||
export const GET_AUTHPAGE_API = `/api/GetUsrFroList`;
|
||||
export const GET_SUBAUTHPAGE_API = `/api/Device/GetMainSub`;
|
||||
export const GET_ALL_DEVICE_API = `/api/Device/GetAllDevice`;
|
90
src/apis/building/index.js
Normal file
@ -0,0 +1,90 @@
|
||||
import {
|
||||
GET_BUILDING_API,
|
||||
POST_BUILDING_API,
|
||||
DELETE_BUILDING_API,
|
||||
GET_AUTHPAGE_API,
|
||||
GET_SUBAUTHPAGE_API,
|
||||
GET_ALL_DEVICE_API,
|
||||
} from "./api";
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
|
||||
export const getBuildings = async () => {
|
||||
const res = await instance.post(GET_BUILDING_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postBuildings = async ({ full_name, building_guid }) => {
|
||||
const res = await instance.post(POST_BUILDING_API, {
|
||||
full_name,
|
||||
building_guid,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteBuildings = async (building_guid) => {
|
||||
const res = await instance.post(DELETE_BUILDING_API, { building_guid });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAuth = async (lang) => {
|
||||
const res = await instance.post(GET_AUTHPAGE_API, {
|
||||
lang,
|
||||
});
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAllSysSidebar = async (building_guid) => {
|
||||
const res = await instance.post(GET_SUBAUTHPAGE_API, {building_guid});
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getSysSidebar = async (building_tag) => {
|
||||
const res = await instance.post(GET_SUBAUTHPAGE_API, {
|
||||
building_tag,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAllDevice = async () => {
|
||||
const res = await instance.post(GET_ALL_DEVICE_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const ackSingleAlarm = async (uuid) => {
|
||||
const res = await instance.post(
|
||||
`/obix/alarm/${uuid}/ack`,
|
||||
'<obj is="obix:AckAlarmIn"><str name="ackUser" val="obix" /></obj>'
|
||||
);
|
||||
console.log("acked", res);
|
||||
return apihandler(res.code, res, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
13
src/apis/dashboard/api.js
Normal file
@ -0,0 +1,13 @@
|
||||
export const GET_DASHBOARD_INIT_API = `/SituationRoom/Initialize`;
|
||||
export const GET_DASHBOARD_DEVICE_API = `/SituationRoom/GetDeviceList`;
|
||||
export const GET_DASHBOARD_PRODUCT_COMPLETE_API = `/SituationRoom/GetProductionStatus`;
|
||||
export const GET_DASHBOARD_TEMP_API = `/SituationRoom/GetTempratureData`;
|
||||
export const GET_DASHBOARD_ROOM_TEMP_API = `/SituationRoom/GetFormulaRoomStatusData`;
|
||||
export const GET_DASHBOARD_ENERGY_API = `/SituationRoom/GetEnergeData`;
|
||||
export const POST_DASHBOARD_PRODUCT_TARGET_SETTING_API = `/SituationRoom/SetTargetSetting`;
|
||||
export const GET_DASHBOARD_PRODUCT_TARGET_SETTING_API = `/SituationRoom/GetTargetSetting`
|
||||
export const GET_DASHBOARD_PRODUCT_HISTORY_API = `/SituationRoom/GetProductionHistory`
|
||||
|
||||
export const GET_DASHBOARD_ENERGY_INFO_API = `api/dashboard/GetEnergyInfo`
|
||||
export const GET_DASHBOARD_ENERGY_COST_API = `api/dashboard/GetEnergyCost`
|
||||
export const GET_DASHBOARD_ALARMOPERATION_INFO_API = `api/dashboard/GetAlarmOperationInfo`
|
178
src/apis/dashboard/index.js
Normal file
@ -0,0 +1,178 @@
|
||||
import {
|
||||
GET_DASHBOARD_INIT_API,
|
||||
GET_DASHBOARD_DEVICE_API,
|
||||
GET_DASHBOARD_PRODUCT_COMPLETE_API,
|
||||
GET_DASHBOARD_TEMP_API,
|
||||
GET_DASHBOARD_ROOM_TEMP_API,
|
||||
GET_DASHBOARD_ENERGY_API,
|
||||
POST_DASHBOARD_PRODUCT_TARGET_SETTING_API,
|
||||
GET_DASHBOARD_PRODUCT_TARGET_SETTING_API,
|
||||
GET_DASHBOARD_PRODUCT_HISTORY_API,
|
||||
GET_DASHBOARD_ENERGY_INFO_API,
|
||||
GET_DASHBOARD_ENERGY_COST_API,
|
||||
GET_DASHBOARD_ALARMOPERATION_INFO_API,
|
||||
} from "./api";
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
|
||||
export const getDashboardInit = async (page_type = "SR") => {
|
||||
const res = await instance.post(GET_DASHBOARD_INIT_API, {
|
||||
page_type, // SR:戰情室;PS:生產設定
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getDashboardDevice = async ({ option }) => {
|
||||
const res = await instance.post(GET_DASHBOARD_DEVICE_API, {
|
||||
option: parseInt(option),
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getDashboardProductCompletion = async () => {
|
||||
const res = await instance.post(GET_DASHBOARD_PRODUCT_COMPLETE_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getDashboardEnergy = async () => {
|
||||
const res = await instance.post(GET_DASHBOARD_ENERGY_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getDashboardFormulaRoom = async ({ timeInterval, typeOption }) => {
|
||||
const res = await instance.post(GET_DASHBOARD_ROOM_TEMP_API, {
|
||||
timeInterval,
|
||||
typeOption,
|
||||
});
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getDashboardTemp = async ({
|
||||
timeInterval,
|
||||
tempOption,
|
||||
typeOption = "",
|
||||
}) => {
|
||||
const res = typeOption
|
||||
? await instance.post(GET_DASHBOARD_TEMP_API, {
|
||||
timeInterval,
|
||||
tempOption,
|
||||
typeOption,
|
||||
})
|
||||
: await instance.post(GET_DASHBOARD_TEMP_API, {
|
||||
timeInterval,
|
||||
tempOption,
|
||||
});
|
||||
console.log(res);
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postDashboardProductTarget = async ({ date, type, data }) => {
|
||||
let formatData = [];
|
||||
|
||||
for (let [key, value] of Object.entries(data)) {
|
||||
formatData.push({
|
||||
name: key,
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
const res = await instance.post(POST_DASHBOARD_PRODUCT_TARGET_SETTING_API, {
|
||||
target: {
|
||||
date,
|
||||
type,
|
||||
data: formatData,
|
||||
},
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getDashboardProductTarget = async ({ date, type }) => {
|
||||
const res = await instance.post(GET_DASHBOARD_PRODUCT_TARGET_SETTING_API, {
|
||||
target: {
|
||||
date,
|
||||
type,
|
||||
},
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getDashboardProductRecord = async ({ start_time, end_time }) => {
|
||||
const res = await instance.post(GET_DASHBOARD_PRODUCT_HISTORY_API, {
|
||||
start_time,
|
||||
end_time,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getEnergyInfo = async (building_guid) => {
|
||||
const res = await instance.post(GET_DASHBOARD_ENERGY_INFO_API, {
|
||||
building_guid,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getEnergyCost = async ({
|
||||
department_id,
|
||||
floor_guid,
|
||||
building_guid,
|
||||
}) => {
|
||||
const res = await instance.post(GET_DASHBOARD_ENERGY_COST_API, {
|
||||
department_id,
|
||||
floor_guid,
|
||||
building_guid,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAlarmOperationInfo = async (building_guid) => {
|
||||
const res = await instance.post(GET_DASHBOARD_ALARMOPERATION_INFO_API, {
|
||||
building_guid,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
23
src/apis/energy/api.js
Normal file
@ -0,0 +1,23 @@
|
||||
export const GET_REALTIME_DIST_API = `/api/Energe/GetRealTimeDistribution`;
|
||||
export const GET_ELECUSE_DAY_API = `/api/Energe/GetElecUseDay`;
|
||||
export const GET_TAI_POWER_API = `/api/Energe/GetTaipower`;
|
||||
|
||||
export const GET_SIDEBAR_API = `/api/GetSideBar`;
|
||||
export const GET_SEARCH_API = `/api/Energe/GetFilter`;
|
||||
|
||||
export const GET_REPORT_API = `/api/Energe/GetReport`;
|
||||
export const GET_Excel_API = `/api/Energe/GetReportExcel`;
|
||||
|
||||
// 即時需量
|
||||
export const GET_DEMAND_API = `/api/Energe/SearchDemandValue`;
|
||||
export const POST_ADD_DEMAND_API = `/api/Energe/AddDemandValue`;
|
||||
export const POST_EDIT_DEMAND_API = `/api/Energe/UpdateDemandValue`;
|
||||
export const GET_REALTIME_DEMAND_API = `/api/Energe/GetRealTimeDemand`;
|
||||
|
||||
// 碳排係數
|
||||
export const GET_CARBON_API = `/api/Energe/SearchCarbonValue`;
|
||||
export const POST_EDIT_CARBON_API = `/api/Energe/UpdateCarbonValue`;
|
||||
|
||||
// 時間電價
|
||||
export const GET_TIME_ELEC_API = `/api/Energe/SearchTimeElec`;
|
||||
export const POST_TIME_ELEC_API = `/api/Energe/UpdateTimeElecValue`;
|
232
src/apis/energy/index.js
Normal file
@ -0,0 +1,232 @@
|
||||
import {
|
||||
GET_REALTIME_DIST_API,
|
||||
GET_ELECUSE_DAY_API,
|
||||
GET_TAI_POWER_API,
|
||||
GET_SIDEBAR_API,
|
||||
GET_SEARCH_API,
|
||||
GET_REPORT_API,
|
||||
GET_Excel_API,
|
||||
GET_DEMAND_API,
|
||||
POST_EDIT_DEMAND_API,
|
||||
GET_REALTIME_DEMAND_API,
|
||||
GET_CARBON_API,
|
||||
POST_EDIT_CARBON_API,
|
||||
GET_TIME_ELEC_API,
|
||||
POST_TIME_ELEC_API,
|
||||
} from "./api";
|
||||
import instance, { fileInstance } from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
import downloadExcel from "@/util/downloadExcel";
|
||||
|
||||
export const getRealTimeDist = async ({
|
||||
building_guid,
|
||||
department_id_list,
|
||||
floor_guid_list,
|
||||
}) => {
|
||||
const res = await instance.post(GET_REALTIME_DIST_API, {
|
||||
building_guid,
|
||||
department_id_list,
|
||||
floor_guid_list,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getElecUseDay = async ({
|
||||
building_guid,
|
||||
department_id_list,
|
||||
floor_guid_list,
|
||||
}) => {
|
||||
const res = await instance.post(GET_ELECUSE_DAY_API,{
|
||||
building_guid,
|
||||
department_id_list,
|
||||
floor_guid_list,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getTaipower = async ({
|
||||
coefficient,
|
||||
building_guid,
|
||||
department_id_list,
|
||||
floor_guid_list,
|
||||
}) => {
|
||||
const res = await instance.post(GET_TAI_POWER_API, {
|
||||
coefficient,
|
||||
building_guid,
|
||||
department_id_list,
|
||||
floor_guid_list,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getSideBar = async (system_type) => {
|
||||
const res = await instance.post(GET_SIDEBAR_API, { system_type });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getEnergySearch = async (type) => {
|
||||
const res = await instance.post(GET_SEARCH_API, { type });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getReport = async ({
|
||||
department,
|
||||
elecType,
|
||||
floor,
|
||||
start_time,
|
||||
end_time,
|
||||
type,
|
||||
}) => {
|
||||
const res = await instance.post(GET_REPORT_API, {
|
||||
department,
|
||||
elecType,
|
||||
floor,
|
||||
start_time,
|
||||
end_time,
|
||||
type,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getExcel = async ({
|
||||
department,
|
||||
elecType,
|
||||
floor,
|
||||
start_time,
|
||||
end_time,
|
||||
type,
|
||||
}) => {
|
||||
const res = await fileInstance.post(
|
||||
GET_Excel_API,
|
||||
{
|
||||
department,
|
||||
elecType,
|
||||
floor,
|
||||
start_time,
|
||||
end_time,
|
||||
type,
|
||||
},
|
||||
{ responseType: "blob" }
|
||||
);
|
||||
|
||||
return apihandler(
|
||||
res.code,
|
||||
res,
|
||||
{
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
},
|
||||
downloadExcel
|
||||
);
|
||||
};
|
||||
|
||||
export const getDemand = async (building_guid) => {
|
||||
const res = await instance.post(GET_DEMAND_API, { building_guid });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postEditDemand = async ({
|
||||
id,
|
||||
contract,
|
||||
alert,
|
||||
reset,
|
||||
building_guid,
|
||||
}) => {
|
||||
const res = await instance.put(POST_EDIT_DEMAND_API, {
|
||||
id,
|
||||
contract,
|
||||
alert,
|
||||
reset,
|
||||
building_guid,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getCarbonValue = async (building_guid) => {
|
||||
const res = await instance.post(GET_CARBON_API, { building_guid });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postEditCarbonValue = async ({
|
||||
id,
|
||||
coefficient,
|
||||
building_guid,
|
||||
}) => {
|
||||
const res = await instance.put(POST_EDIT_CARBON_API, {
|
||||
id,
|
||||
coefficient,
|
||||
building_guid,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getRealTimeDemand = async (building_guid) => {
|
||||
const res = await instance.post(GET_REALTIME_DEMAND_API, { building_guid });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getTimeElec = async (building_guid) => {
|
||||
const res = await instance.post(GET_TIME_ELEC_API, { building_guid });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postTimeElec = async ({ sheet, cost, building_guid }) => {
|
||||
const res = await instance.put(POST_TIME_ELEC_API, {
|
||||
sheet,
|
||||
cost,
|
||||
building_guid,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
3
src/apis/forge/api.js
Normal file
@ -0,0 +1,3 @@
|
||||
export const GET_FORGETOKEN_API = `/api/forge/oauth/token`;
|
||||
|
||||
export const GET_FORGEURN_API = `/api/Device/GetBuild`;
|
24
src/apis/forge/index.js
Normal file
@ -0,0 +1,24 @@
|
||||
import instance from "@/util/request";
|
||||
import { GET_FORGETOKEN_API, GET_FORGEURN_API } from "./api";
|
||||
import apihandler from "@/util/apihandler";
|
||||
|
||||
export const getUrn = async () => {
|
||||
const res = await instance.post(GET_FORGEURN_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getAccessToken = async (callback) => {
|
||||
try {
|
||||
const resp = await instance.get(GET_FORGETOKEN_API);
|
||||
console.log(resp)
|
||||
const { dictionary } = resp;
|
||||
callback(dictionary.access_token, dictionary.expires_in);
|
||||
} catch (err) {
|
||||
alert("Could not obtain access token. See the console for more details.");
|
||||
console.error(err);
|
||||
}
|
||||
};
|
16
src/apis/graph/api.js
Normal file
@ -0,0 +1,16 @@
|
||||
// graph
|
||||
const BASEURL = import.meta.env.VITE_API_BASEURL;
|
||||
export const GET_GRAPH_SIDEBAR_API = `/GraphManage/GraphManageTreeList`;
|
||||
|
||||
export const UPDATE_GRAPH_SIDEBAR_API = `/GraphManage/EditGraphManageTree`;
|
||||
export const REMOVE_GRAPH_SIDEBAR_API = `/GraphManage/DelGraphManageTree`;
|
||||
export const POST_GRAPH_SIDEBAR_API = `/GraphManage/SaveGraphManageTree`;
|
||||
|
||||
export const GET_GRAPH_PARAM_OPTION_API = `/GraphManage/GraManSpecList`;
|
||||
|
||||
export const GET_GRAPH_TABLE_API = `/GraphManage/GraManList`;
|
||||
export const POST_GRAPH_TABLE_API = `/GraphManage/SaveGraMan`;
|
||||
export const POST_GRAPH_TABLE_API_2 = `/GraphManage/SaveGraMan`; // 原先沒有小類及規格的
|
||||
export const UPDATE_GRAPH_TABLE_API = `/GraphManage/EdtOneGraMan`;
|
||||
|
||||
export const DELETE_GRAPH_TABLE_API = `/GraphManage/DelOneGraMan`;
|
122
src/apis/graph/index.js
Normal file
@ -0,0 +1,122 @@
|
||||
import {
|
||||
GET_GRAPH_SIDEBAR_API,
|
||||
UPDATE_GRAPH_SIDEBAR_API,
|
||||
REMOVE_GRAPH_SIDEBAR_API,
|
||||
POST_GRAPH_SIDEBAR_API,
|
||||
GET_GRAPH_TABLE_API,
|
||||
GET_GRAPH_PARAM_OPTION_API,
|
||||
POST_GRAPH_TABLE_API,
|
||||
DELETE_GRAPH_TABLE_API,
|
||||
POST_GRAPH_TABLE_API_2,
|
||||
UPDATE_GRAPH_TABLE_API
|
||||
} from "./api";
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apiHandler";
|
||||
|
||||
export const getSideBar = async () => {
|
||||
const res = await instance.post(GET_GRAPH_SIDEBAR_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const addSideBarTreeName = async ({ parent_id, name }) => {
|
||||
const res = await instance.post(POST_GRAPH_SIDEBAR_API, { parent_id, name });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const updateSideBarTreeName = async ({ id, name }) => {
|
||||
const res = await instance.post(UPDATE_GRAPH_SIDEBAR_API, { id, name });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const removeSideBarTreeName = async (id) => {
|
||||
const res = await instance.post(REMOVE_GRAPH_SIDEBAR_API, { id });
|
||||
|
||||
return apihandler(
|
||||
res.code,
|
||||
{ isSuccess: true },
|
||||
{
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
isSuccess: false,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// 中間 table
|
||||
export const getGraphData = async (id) => {
|
||||
const res = await instance.post(GET_GRAPH_TABLE_API, { layer_id: id });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
isSuccess: false,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGraphAddParamOption = async () => {
|
||||
const res = await instance.post(GET_GRAPH_PARAM_OPTION_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
isSuccess: false,
|
||||
});
|
||||
};
|
||||
|
||||
export const addGraphTableData = async (formData) => {
|
||||
const res = await instance.post(POST_GRAPH_TABLE_API, formData);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
isSuccess: false,
|
||||
});
|
||||
};
|
||||
|
||||
export const delGraphData = async (id, hard_delete = false, recover_delete = false) => {
|
||||
const res = await instance.post(DELETE_GRAPH_TABLE_API, { id, hard_delete, recover_delete });
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
isSuccess: false,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
export const addGraphTableDataWithoutSubSys = async (formData) => {
|
||||
const res = await instance.post(POST_GRAPH_TABLE_API_2, formData);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
isSuccess: false,
|
||||
});
|
||||
};
|
||||
|
||||
export const editGraphTableDataWithoutSubSys = async (formData) => {
|
||||
const res = await instance.post(UPDATE_GRAPH_TABLE_API, formData);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
isSuccess: false,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
11
src/apis/history/api.js
Normal file
@ -0,0 +1,11 @@
|
||||
// history
|
||||
const BASEURL = import.meta.env.VITE_API_BASEURL;
|
||||
export const GET_HISTORY_SIDEBAR_API = `/api/History/GetDeviceInfo`;
|
||||
export const GET_HISTORY_POINT_API = `/api/History/GetAllDevPoi`;
|
||||
export const GET_HISTORY_DATA_API = `/api/History/GetHistoryData`;
|
||||
export const GET_HISTORY_EXPORT_API = `/api/ExportHistoryExcel`;
|
||||
|
||||
export const GET_HISTORY_FAVORITE_API = `/api/History/GetHistoryFavorite`;
|
||||
export const POST_HISTORY_FAVORITE_API = `/api/History/SaveHistoryFavorite`;
|
||||
export const DELETE_HISTORY_FAVORITE_API = `/api/History/DeleteHistoryFavorite`;
|
||||
export const UPDATE_HISTORY_FAVORITE_API = `/api/History/EditHistoryFavorite`;
|
177
src/apis/history/index.js
Normal file
@ -0,0 +1,177 @@
|
||||
import {
|
||||
GET_HISTORY_SIDEBAR_API,
|
||||
GET_HISTORY_POINT_API,
|
||||
GET_HISTORY_DATA_API,
|
||||
GET_HISTORY_FAVORITE_API,
|
||||
POST_HISTORY_FAVORITE_API,
|
||||
DELETE_HISTORY_FAVORITE_API,
|
||||
UPDATE_HISTORY_FAVORITE_API,
|
||||
GET_HISTORY_EXPORT_API,
|
||||
} from "./api";
|
||||
import instance, { fileInstance } from "@/util/request";
|
||||
import apihandler from "@/util/apiHandler";
|
||||
import downloadExcel from "@/util/downloadExcel";
|
||||
|
||||
export const getHistorySideBar = async ({
|
||||
sub_system_tag,
|
||||
department_id,
|
||||
elec_type_id,
|
||||
building_guid,
|
||||
}) => {
|
||||
const res = await instance.post(GET_HISTORY_SIDEBAR_API, {
|
||||
sub_system_tag,
|
||||
department_id,
|
||||
elec_type_id,
|
||||
building_guid,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getHistoryPoints = async (Device_list) => {
|
||||
const res = await instance.post(GET_HISTORY_POINT_API, {
|
||||
Device_list,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getHistoryData = async ({
|
||||
Type,
|
||||
Start_date,
|
||||
End_date,
|
||||
Start_time,
|
||||
End_time,
|
||||
Device_list,
|
||||
Points,
|
||||
table_type,
|
||||
}) => {
|
||||
/*
|
||||
{
|
||||
Type,
|
||||
Start_date,
|
||||
End_date,
|
||||
Start_time,
|
||||
End_time,
|
||||
Device_list,
|
||||
Points,
|
||||
}
|
||||
*/
|
||||
const res = await instance.post(GET_HISTORY_DATA_API, {
|
||||
Start_date,
|
||||
End_date,
|
||||
Start_time,
|
||||
End_time,
|
||||
Device_list: Array.isArray(Device_list) ? Device_list : [Device_list],
|
||||
Points: Array.isArray(Points) ? Points : [Points],
|
||||
Type: parseInt(Type),
|
||||
table_type: parseInt(table_type),
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getHistoryExportData = async ({
|
||||
Type,
|
||||
Start_date,
|
||||
End_date,
|
||||
Start_time,
|
||||
End_time,
|
||||
Device_list,
|
||||
Points,
|
||||
}) => {
|
||||
/*
|
||||
{
|
||||
Type,
|
||||
Start_date,
|
||||
End_date,
|
||||
Start_time,
|
||||
End_time,
|
||||
Device_list,
|
||||
Points,
|
||||
}
|
||||
*/
|
||||
const res = await fileInstance.post(
|
||||
GET_HISTORY_EXPORT_API,
|
||||
{
|
||||
// ...exportContent,
|
||||
Start_date: Start_date,
|
||||
End_date: End_date,
|
||||
Start_time: Start_time,
|
||||
End_time: End_time,
|
||||
Points: Array.isArray(Points) ? Points : [Points],
|
||||
Device_list: Array.isArray(Device_list) ? Device_list : [Device_list],
|
||||
Type: parseInt(Type),
|
||||
Building_tag_list: [...new Set(Device_list.map((d) => d.split("_")[1]))],
|
||||
},
|
||||
{ responseType: "blob" }
|
||||
);
|
||||
|
||||
return apihandler(
|
||||
res.code,
|
||||
res,
|
||||
{
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
},
|
||||
downloadExcel
|
||||
);
|
||||
};
|
||||
|
||||
export const getHistoryFavorite = async () => {
|
||||
const res = await instance.post(GET_HISTORY_FAVORITE_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const addHistoryFavorite = async (value) => {
|
||||
const res = await instance.post(POST_HISTORY_FAVORITE_API, {
|
||||
device_name_tag: value.sub_system_tag,
|
||||
Device_list: Array.isArray(value.Device_list)
|
||||
? value.Device_list
|
||||
: [value.Device_list],
|
||||
Points: Array.isArray(value.Points) ? value.Points : [value.Points],
|
||||
favorite_name: value.favorite_name,
|
||||
Type: parseInt(value.Type),
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteHistoryFavorite = async (favorite_guid) => {
|
||||
const res = await instance.post(DELETE_HISTORY_FAVORITE_API, {
|
||||
favorite_guid,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const editHistoryFavorite = async ({ favorite_guid, favorite_name }) => {
|
||||
const res = await instance.post(UPDATE_HISTORY_FAVORITE_API, {
|
||||
favorite_guid,
|
||||
favorite_name,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
1
src/apis/login/api.js
Normal file
@ -0,0 +1 @@
|
||||
export const POST_LOGIN = `/api/LoginV2/`;
|
27
src/apis/login/index.js
Normal file
@ -0,0 +1,27 @@
|
||||
import { POST_LOGIN } from "./api";
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
|
||||
export async function Login({ account, password }) {
|
||||
const res = await instance.post(POST_LOGIN, {
|
||||
account,
|
||||
password,
|
||||
});
|
||||
|
||||
if (res.code === "0000") {
|
||||
console.log(res.data);
|
||||
document.cookie = `JWT-Authorization=${res.data.token}; Max-Age=${
|
||||
24 * 60 * 60 * 1000
|
||||
}`;
|
||||
// 設定 user_name Cookie
|
||||
document.cookie = `user_name=${res.data.user_name}; Max-Age=${
|
||||
24 * 60 * 60 * 1000
|
||||
}`;
|
||||
}
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
isSuccess: false,
|
||||
});
|
||||
}
|
16
src/apis/operation/api.js
Normal file
@ -0,0 +1,16 @@
|
||||
export const GET_OPERATION_RECORD_API = `/operation/OpeRecList`;
|
||||
export const GET_OPERATION_EXPORT_API = `/operation/OpeExportExcel`;
|
||||
export const GET_OPERATION_DEVICELIST_API = `/operation/DevList`;
|
||||
export const GET_OPERATION_COMPANYLIST_API = `/operation/OpeFirSel`;
|
||||
|
||||
export const GET_SINGLE_OPERATION_RECORD_API = `/operation/OpeRecRead`;
|
||||
export const GET_OPERATION_FORMID_API = `/operation/GetFormId`; // 新增單號前置
|
||||
export const POST_OPERATION_RECORD_API = `/operation/SavOpeRecord`;
|
||||
export const DELETE_OPERATION_RECORD_API = `/operation/DelOpeRecord`;
|
||||
|
||||
// 廠商
|
||||
export const GET_OPERATION_COMPANY_API = `/operation/OpeFirList`; // 廠商列表
|
||||
export const GET_OPERATION_SINGLE_CONPANY_API = `/operation/OpeFirRead`; // 單一廠商
|
||||
export const POST_OPERATION_COMPANY_API = `/operation/SaveOpeFirm`;
|
||||
export const UPDATE_OPERATION_COMPANY_API = `/operation/EdtOneOpeFirm`;
|
||||
export const DELETE_OPERATION_COMPANY_API = `/operation/DelOpeFirm`;
|
190
src/apis/operation/index.js
Normal file
@ -0,0 +1,190 @@
|
||||
import {
|
||||
GET_OPERATION_RECORD_API,
|
||||
GET_OPERATION_COMPANY_API,
|
||||
GET_SINGLE_OPERATION_RECORD_API,
|
||||
GET_OPERATION_DEVICELIST_API,
|
||||
POST_OPERATION_RECORD_API,
|
||||
GET_OPERATION_EXPORT_API,
|
||||
GET_OPERATION_FORMID_API,
|
||||
DELETE_OPERATION_RECORD_API,
|
||||
POST_OPERATION_COMPANY_API,
|
||||
UPDATE_OPERATION_COMPANY_API,
|
||||
DELETE_OPERATION_COMPANY_API,
|
||||
} from "./api";
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export const getOperationRecord = async ({
|
||||
work_type,
|
||||
start_created_at,
|
||||
end_created_at,
|
||||
serial_number,
|
||||
sub_system_tag,
|
||||
}) => {
|
||||
const res = await instance.post(GET_OPERATION_RECORD_API, {
|
||||
work_type: parseInt(work_type),
|
||||
// start_created_at: dayjs(start_created_at).format("YYYY-MM-DDTHH:mm:ss"),
|
||||
// end_created_at: dayjs(end_created_at)
|
||||
// .date(dayjs(end_created_at).get("date") + 1)
|
||||
// .format("YYYY-MM-DDTHH:mm:ss"),
|
||||
serial_number: serial_number || null,
|
||||
main_system_tag: null,
|
||||
sub_system_tag:
|
||||
typeof sub_system_tag === "string" ? [sub_system_tag] : sub_system_tag,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getOperationExportRecord = async ({
|
||||
work_type,
|
||||
start_created_at,
|
||||
end_created_at,
|
||||
}) => {
|
||||
const res = await instance.post(GET_OPERATION_EXPORT_API, {
|
||||
work_type: parseInt(work_type),
|
||||
startdate: dayjs(start_created_at).format("YYYY-MM-DDTHH:mm:ss"),
|
||||
enddate: dayjs(end_created_at)
|
||||
.date(dayjs(end_created_at).get("date") + 1)
|
||||
.format("YYYY-MM-DDTHH:mm:ss"),
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getOperationCompanyList = async () => {
|
||||
const res = await instance.post(GET_OPERATION_COMPANY_API, {
|
||||
sub_system_tag: [],
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getOperationDeviceList = async ({
|
||||
list_sub_system_tag,
|
||||
device_building_tag,
|
||||
device_area_tag,
|
||||
}) => {
|
||||
const res = await instance.post(GET_OPERATION_DEVICELIST_API, {
|
||||
list_sub_system_tag:
|
||||
typeof list_sub_system_tag === "string"
|
||||
? [list_sub_system_tag]
|
||||
: list_sub_system_tag,
|
||||
device_building_tag,
|
||||
device_area_tag,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getOperationEditRecord = async (formId) => {
|
||||
const res = await instance.post(GET_SINGLE_OPERATION_RECORD_API, {
|
||||
formId,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const postOperationRecord = async (formData) => {
|
||||
const res = await instance.post(POST_OPERATION_RECORD_API, formData);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getOperationFormId = async () => {
|
||||
const res = await instance.post(GET_OPERATION_FORMID_API, {});
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteOperationRecord = async (id) => {
|
||||
const res = await instance.post(DELETE_OPERATION_RECORD_API, { id });
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
// 公司
|
||||
export const postOperationCompany = async ({
|
||||
name,
|
||||
contact_person,
|
||||
phone,
|
||||
email,
|
||||
city,
|
||||
address,
|
||||
tax_id_number,
|
||||
remark,
|
||||
}) => {
|
||||
const res = await instance.post(POST_OPERATION_COMPANY_API, {
|
||||
name,
|
||||
contact_person,
|
||||
phone,
|
||||
email,
|
||||
city,
|
||||
address,
|
||||
tax_id_number,
|
||||
remark,
|
||||
});
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const updateOperationCompany = async ({
|
||||
name,
|
||||
contact_person,
|
||||
phone,
|
||||
email,
|
||||
city,
|
||||
address,
|
||||
tax_id_number,
|
||||
remark,
|
||||
id,
|
||||
}) => {
|
||||
const res = await instance.post(UPDATE_OPERATION_COMPANY_API, {
|
||||
id,
|
||||
name,
|
||||
contact_person,
|
||||
phone,
|
||||
email,
|
||||
city,
|
||||
address,
|
||||
tax_id_number,
|
||||
remark,
|
||||
});
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteOperationCompany = async (id) => {
|
||||
const res = await instance.post(DELETE_OPERATION_COMPANY_API, { id });
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
4
src/apis/productSetting/api.js
Normal file
@ -0,0 +1,4 @@
|
||||
export const POST_SETTING_POINT_API = `/SituationRoom/SetPointSetting`;
|
||||
|
||||
export const GET_SETTING_TYPE_API = `/SituationRoom/GetProducts`;
|
||||
export const POST_SETTING_TYPE_API = `/SituationRoom/SetProduct`;
|
45
src/apis/productSetting/index.js
Normal file
@ -0,0 +1,45 @@
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
import {
|
||||
POST_SETTING_POINT_API,
|
||||
GET_SETTING_TYPE_API,
|
||||
POST_SETTING_TYPE_API,
|
||||
} from "./api";
|
||||
|
||||
export const postProductSettingPoint = async (type, devices) => {
|
||||
const res = await instance.post(POST_SETTING_POINT_API, {
|
||||
devices: devices.map(({ device_number }) => device_number),
|
||||
values: [
|
||||
{
|
||||
point: "Type",
|
||||
value: type.value,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
isSuccess: false,
|
||||
});
|
||||
};
|
||||
|
||||
export const getProductSettingType = async () => {
|
||||
const res = await instance.post(GET_SETTING_TYPE_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
isSuccess: false,
|
||||
});
|
||||
};
|
||||
|
||||
export const postProductSettingType = async (data) => {
|
||||
const res = await instance.post(POST_SETTING_TYPE_API, data);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
isSuccess: false,
|
||||
});
|
||||
};
|
3
src/apis/system/api.js
Normal file
@ -0,0 +1,3 @@
|
||||
export const GET_SYSTEM_FLOOR_LIST_API = `/api/Device/GetFloor`;
|
||||
export const GET_SYSTEM_DEVICE_LIST_API = `/api/Device/GetDeviceList`;
|
||||
export const GET_SYSTEM_REALTIME_API = `/api/Device/GetRealTimeData`;
|
44
src/apis/system/index.js
Normal file
@ -0,0 +1,44 @@
|
||||
import {
|
||||
GET_SYSTEM_FLOOR_LIST_API,
|
||||
GET_SYSTEM_DEVICE_LIST_API,
|
||||
GET_SYSTEM_REALTIME_API,
|
||||
} from "./api";
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
|
||||
export const getSystemFloors = async (building_tag, sub_system_tag) => {
|
||||
const res = await instance.post(GET_SYSTEM_FLOOR_LIST_API, {
|
||||
building_tag,
|
||||
sub_system_tag,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getSystemDevices = async ({
|
||||
sub_system_tag,
|
||||
building_guid,
|
||||
department_id_list,
|
||||
}) => {
|
||||
const res = await instance.post(GET_SYSTEM_DEVICE_LIST_API, {
|
||||
sub_system_tag,
|
||||
building_guid,
|
||||
department_id_list,
|
||||
});
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getSystemRealTime = async (device_list) => {
|
||||
const res = await instance.post(GET_SYSTEM_REALTIME_API, { device_list });
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
89
src/assets/base.css
Normal file
@ -0,0 +1,89 @@
|
||||
/* color palette from <https://github.com/vuejs/theme> */
|
||||
:root {
|
||||
--primary: #6fdda8;
|
||||
--vt-c-white: #ffffff;
|
||||
--vt-c-white-soft: #f8f8f8;
|
||||
--vt-c-white-mute: #f2f2f2;
|
||||
|
||||
--vt-c-black: #181818;
|
||||
--vt-c-black-soft: #222222;
|
||||
--vt-c-black-mute: #282828;
|
||||
|
||||
--vt-c-indigo: #2c3e50;
|
||||
|
||||
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
|
||||
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
|
||||
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
|
||||
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
|
||||
|
||||
--vt-c-text-light-1: var(--vt-c-indigo);
|
||||
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
|
||||
--vt-c-text-dark-1: var(--vt-c-white);
|
||||
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
|
||||
}
|
||||
|
||||
/* semantic color variables for this project */
|
||||
:root {
|
||||
--color-background: var(--vt-c-white);
|
||||
--color-background-soft: var(--vt-c-white-soft);
|
||||
--color-background-mute: var(--vt-c-white-mute);
|
||||
|
||||
--color-border: var(--vt-c-divider-light-2);
|
||||
--color-border-hover: var(--vt-c-divider-light-1);
|
||||
|
||||
--color-heading: var(--vt-c-text-light-1);
|
||||
--color-text: var(--vt-c-text-dark-1);
|
||||
|
||||
--section-gap: 160px;
|
||||
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--color-background: var(--vt-c-black);
|
||||
--color-background-soft: var(--vt-c-black-soft);
|
||||
--color-background-mute: var(--vt-c-black-mute);
|
||||
|
||||
--color-border: var(--vt-c-divider-dark-2);
|
||||
--color-border-hover: var(--vt-c-divider-dark-1);
|
||||
|
||||
--color-heading: var(--vt-c-text-dark-1);
|
||||
--color-text: var(--vt-c-text-dark-2);
|
||||
}
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
color: var(--color-text);
|
||||
background: var(--color-background);
|
||||
transition:
|
||||
color 0.5s,
|
||||
background-color 0.5s;
|
||||
line-height: 1.6;
|
||||
font-family:
|
||||
Inter,
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
'Segoe UI',
|
||||
Roboto,
|
||||
Oxygen,
|
||||
Ubuntu,
|
||||
Cantarell,
|
||||
'Fira Sans',
|
||||
'Droid Sans',
|
||||
'Helvetica Neue',
|
||||
sans-serif;
|
||||
font-size: 15px;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
}
|
56
src/assets/btn.css
Normal file
@ -0,0 +1,56 @@
|
||||
/**區域框**/
|
||||
.area-box {
|
||||
/* width: 100%; */
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.area-box .item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.area-box .item button:last-child::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.area-box .item button::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: -15px;
|
||||
margin: auto;
|
||||
display: block;
|
||||
width: 15px;
|
||||
height: 1px;
|
||||
background-color: #a1ffd6;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.area-box .item button {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-radius: 5px;
|
||||
margin: 0 7px;
|
||||
background-color: #021422;
|
||||
padding: 0.5rem 0;
|
||||
min-width: 65px;
|
||||
color: #fff;
|
||||
border: 1px solid #a1ffd6 !important;
|
||||
text-align: center;
|
||||
margin-bottom: 15px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.area-box .item button.active {
|
||||
background-color: #6fdda8;
|
||||
text-shadow: 0px 0px 5px rgba(0, 0, 0, 0.9);
|
||||
box-shadow: 0px 0px 5px rgba(255, 255, 255, 0.8);
|
||||
}
|
BIN
src/assets/img/area-img-box-line-bottom.png
Normal file
After Width: | Height: | Size: 524 B |
BIN
src/assets/img/area-img-box-line-top.png
Normal file
After Width: | Height: | Size: 530 B |
BIN
src/assets/img/background.jpg
Normal file
After Width: | Height: | Size: 94 KiB |
1
src/assets/img/chart-data-background01.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:#dff3fa;}.cls-2{fill:#74b6ed;}</style></defs><path class="cls-1" d="M2.79,24.12a2.59,2.59,0,0,0,2.58-2.58V7.1A5,5,0,0,0,7.11,5.4H21.23a2.59,2.59,0,0,0,2.58-2.58.12.12,0,0,0-.12-.12.12.12,0,0,0-.12.12,2.34,2.34,0,0,1-2.34,2.34H7l0,.06A4.86,4.86,0,0,1,5.19,6.93L5.13,7V21.54a2.34,2.34,0,0,1-2.34,2.34.12.12,0,0,0-.12.12A.12.12,0,0,0,2.79,24.12Z"/><path class="cls-2" d="M2,18.05a.6.6,0,0,1-.6-.59V4.14L1,3.86A2.09,2.09,0,0,1,2.09,0,2.05,2.05,0,0,1,3.88,1l.28.46H17a.6.6,0,0,1,.6.6.59.59,0,0,1-.6.59H4.16l-.28.47a2.08,2.08,0,0,1-.77.76l-.49.27V17.46A.59.59,0,0,1,2,18.05Z"/></svg>
|
After Width: | Height: | Size: 697 B |
1
src/assets/img/chart-data-background02.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:#dff3fa;}.cls-2{fill:#74b6ed;}</style></defs><path class="cls-1" d="M-.15,21.18A2.58,2.58,0,0,1,2.43,18.6H16.87a4.88,4.88,0,0,1,1.7-1.74V2.74A2.59,2.59,0,0,1,21.15.15a.12.12,0,0,1,.12.12.12.12,0,0,1-.12.12,2.35,2.35,0,0,0-2.34,2.35V17l-.06,0A4.63,4.63,0,0,0,17,18.78l0,.06H2.43A2.35,2.35,0,0,0,.08,21.18.12.12,0,0,1,0,21.3.11.11,0,0,1-.15,21.18Z"/><path class="cls-2" d="M5.92,21.94a.59.59,0,0,0,.59.6H19.83l.28.44a2.07,2.07,0,0,0,1.77,1,2.09,2.09,0,0,0,1.06-3.89l-.47-.27V7a.59.59,0,0,0-.59-.6.6.6,0,0,0-.6.6V19.81l-.46.27a2.11,2.11,0,0,0-.76.78l-.28.48H6.51A.59.59,0,0,0,5.92,21.94Z"/></svg>
|
After Width: | Height: | Size: 713 B |
1
src/assets/img/chart-data-background03.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8"><defs><style>.cls-1{fill:#0ca9d4;}</style></defs><polygon id="_13" data-name="13" class="cls-1" points="3.96 0 4.48 3.43 7.91 3.96 4.48 4.48 3.96 7.91 3.43 4.48 0 3.96 3.43 3.43 3.96 0"/></svg>
|
After Width: | Height: | Size: 286 B |
21
src/assets/img/chart-title01.svg
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 124.4 12" style="enable-background:new 0 0 124.4 12;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#17CEE3;}
|
||||
.st1{opacity:0.3;fill:#969696;}
|
||||
.st2{opacity:0.8;fill:#17CEE3;}
|
||||
</style>
|
||||
<g>
|
||||
<polygon class="st0" points="92.7,2.9 31.5,2.9 28.8,0 95.6,0 "/>
|
||||
<path class="st1" d="M124.4,0.1v11.7c0,0.1-0.3,0.1-0.7,0.1H97.8c-0.2,0-0.4,0-0.5-0.1l-1.8-0.4c-0.1,0-0.3-0.1-0.5-0.1H29.8
|
||||
c-0.2,0-0.4,0-0.5,0.1L27.5,12C27.4,12,27.2,12,27,12H0.7C0.3,12,0,11.9,0,11.9V0.1C0,0.1,0.3,0,0.7,0l26.2,0.1
|
||||
c0.2,0,0.4,0,0.5,0.1L29,2.2c0.1,0,0.3,0.1,0.5,0.1h65.3c0.2,0,0.4,0,0.5-0.1l1.9-2.1c0.1,0,0.3-0.1,0.5-0.1l26-0.1
|
||||
C124.1,0,124.4,0.1,124.4,0.1z"/>
|
||||
<path class="st2" d="M122.9,12V2.1c0-0.5-0.4-0.9-0.9-0.9H96.4c-0.3,0-0.5,0.1-0.7,0.3l-1.8,1.6c-0.1,0.1-0.2,0.1-0.3,0.1H30.7
|
||||
c-0.1,0-0.2,0-0.3-0.1l-1.6-1.6c-0.2-0.2-0.4-0.3-0.7-0.3H2.4c-0.5,0-0.9,0.4-0.9,0.9V12 M1.7,12V2.1c0-0.4,0.3-0.6,0.6-0.6h25.8
|
||||
c0.2,0,0.4,0.1,0.5,0.2l1.6,1.6c0.1,0.1,0.3,0.2,0.5,0.2h62.9c0.2,0,0.4-0.1,0.5-0.2l1.8-1.6c0.1-0.1,0.3-0.2,0.5-0.2H122
|
||||
c0.4,0,0.6,0.3,0.6,0.6V12"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
12
src/assets/img/chart-title02.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 124.4 12.01">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1,.cls-3 { fill: #E4EA00; }
|
||||
.cls-2 { fill: #969696; opacity: 0.3; }
|
||||
.cls-3 { opacity: 0.8; }
|
||||
</style>
|
||||
</defs>
|
||||
<polygon class="cls-1" points="92.68 2.87 31.5 2.87 28.8 0 95.59 0 92.68 2.87"/>
|
||||
<path class="cls-2" d="M124.4.14V11.86c0,.08-.3.15-.66.15H97.84a2.27,2.27,0,0,1-.5,0l-1.76-.45a2.34,2.34,0,0,0-.5,0H29.76a2.2,2.2,0,0,0-.5,0L27.5,12a2.34,2.34,0,0,1-.5,0H.66C.3,12,0,11.94,0,11.86V.14C0,.06.3,0,.66,0L26.87.11a1.79,1.79,0,0,1,.5.05L29,2.25a2.27,2.27,0,0,0,.5,0H94.86a2.34,2.34,0,0,0,.5,0L97.25.16a1.83,1.83,0,0,1,.5,0l26-.11C124.1,0,124.4.06,124.4.14Z"/>
|
||||
<path class="cls-3" d="M122.92,12V2.12a.89.89,0,0,0-.89-.89H96.41a.9.9,0,0,0-.67.31l-1.83,1.6a.36.36,0,0,1-.29.13H30.73a.36.36,0,0,1-.29-.13l-1.6-1.6a.9.9,0,0,0-.67-.31H2.37a.89.89,0,0,0-.89.89V12m.25,0V2.12a.64.64,0,0,1,.64-.64h25.8a.65.65,0,0,1,.48.23l1.6,1.59a.64.64,0,0,0,.48.22H93.62a.62.62,0,0,0,.48-.22l1.83-1.59a.65.65,0,0,1,.48-.23H122a.64.64,0,0,1,.64.64V12"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
21
src/assets/img/chart-title03.svg
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 124.4 12" style="enable-background:new 0 0 124.4 12;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#62E39A;}
|
||||
.st1{opacity:0.3;fill:#969696;}
|
||||
.st2{opacity:0.8;fill:#62E39A;}
|
||||
</style>
|
||||
<g>
|
||||
<polygon class="st0" points="92.7,2.9 31.5,2.9 28.8,0 95.6,0 "/>
|
||||
<path class="st1" d="M124.4,0.1v11.7c0,0.1-0.3,0.1-0.7,0.1H97.8c-0.2,0-0.4,0-0.5-0.1l-1.8-0.4c-0.1,0-0.3-0.1-0.5-0.1H29.8
|
||||
c-0.2,0-0.4,0-0.5,0.1L27.5,12C27.4,12,27.2,12,27,12H0.7C0.3,12,0,11.9,0,11.9V0.1C0,0.1,0.3,0,0.7,0l26.2,0.1
|
||||
c0.2,0,0.4,0,0.5,0.1L29,2.2c0.1,0,0.3,0.1,0.5,0.1h65.3c0.2,0,0.4,0,0.5-0.1l1.9-2.1c0.1,0,0.3-0.1,0.5-0.1l26-0.1
|
||||
C124.1,0,124.4,0.1,124.4,0.1z"/>
|
||||
<path class="st2" d="M122.9,12V2.1c0-0.5-0.4-0.9-0.9-0.9H96.4c-0.3,0-0.5,0.1-0.7,0.3l-1.8,1.6c-0.1,0.1-0.2,0.1-0.3,0.1H30.7
|
||||
c-0.1,0-0.2,0-0.3-0.1l-1.6-1.6c-0.2-0.2-0.4-0.3-0.7-0.3H2.4c-0.5,0-0.9,0.4-0.9,0.9V12 M1.7,12V2.1c0-0.4,0.3-0.6,0.6-0.6h25.8
|
||||
c0.2,0,0.4,0.1,0.5,0.2l1.6,1.6c0.1,0.1,0.3,0.2,0.5,0.2h62.9c0.2,0,0.4-0.1,0.5-0.2l1.8-1.6c0.1-0.1,0.3-0.2,0.5-0.2H122
|
||||
c0.4,0,0.6,0.3,0.6,0.6V12"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
21
src/assets/img/chart-title04.svg
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 124.4 12" style="enable-background:new 0 0 124.4 12;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#E9971F;}
|
||||
.st1{opacity:0.3;fill:#969696;}
|
||||
.st2{opacity:0.8;fill:#E9971F;}
|
||||
</style>
|
||||
<g>
|
||||
<polygon class="st0" points="92.7,2.9 31.5,2.9 28.8,0 95.6,0 "/>
|
||||
<path class="st1" d="M124.4,0.1v11.7c0,0.1-0.3,0.1-0.7,0.1H97.8c-0.2,0-0.4,0-0.5-0.1l-1.8-0.4c-0.1,0-0.3-0.1-0.5-0.1H29.8
|
||||
c-0.2,0-0.4,0-0.5,0.1L27.5,12C27.4,12,27.2,12,27,12H0.7C0.3,12,0,11.9,0,11.9V0.1C0,0.1,0.3,0,0.7,0l26.2,0.1
|
||||
c0.2,0,0.4,0,0.5,0.1L29,2.2c0.1,0,0.3,0.1,0.5,0.1h65.3c0.2,0,0.4,0,0.5-0.1l1.9-2.1c0.1,0,0.3-0.1,0.5-0.1l26-0.1
|
||||
C124.1,0,124.4,0.1,124.4,0.1z"/>
|
||||
<path class="st2" d="M122.9,12V2.1c0-0.5-0.4-0.9-0.9-0.9H96.4c-0.3,0-0.5,0.1-0.7,0.3l-1.8,1.6c-0.1,0.1-0.2,0.1-0.3,0.1H30.7
|
||||
c-0.1,0-0.2,0-0.3-0.1l-1.6-1.6c-0.2-0.2-0.4-0.3-0.7-0.3H2.4c-0.5,0-0.9,0.4-0.9,0.9V12 M1.7,12V2.1c0-0.4,0.3-0.6,0.6-0.6h25.8
|
||||
c0.2,0,0.4,0.1,0.5,0.2l1.6,1.6c0.1,0.1,0.3,0.2,0.5,0.2h62.9c0.2,0,0.4-0.1,0.5-0.2l1.8-1.6c0.1-0.1,0.3-0.2,0.5-0.2H122
|
||||
c0.4,0,0.6,0.3,0.6,0.6V12"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
21
src/assets/img/equipment-item-background.svg
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 2.5 21" style="enable-background:new 0 0 2.5 21;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{opacity:0.8;}
|
||||
.st1{fill:#FDE9F2;}
|
||||
</style>
|
||||
<g id="_x37_0_00000047024518298343511510000016821505459452511412_" class="st0">
|
||||
<rect x="1.2" y="1" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -1.5991 1.79)" class="st1" width="0.3" height="3.6"/>
|
||||
<rect x="1.2" y="-0.4" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -0.5638 1.3612)" class="st1" width="0.3" height="3.6"/>
|
||||
<rect x="1.2" y="5.2" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -4.5762 3.0232)" class="st1" width="0.3" height="3.6"/>
|
||||
<rect x="1.2" y="3.8" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -3.541 2.5943)" class="st1" width="0.3" height="3.6"/>
|
||||
<rect x="1.2" y="9.5" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -7.5533 4.2563)" class="st1" width="0.3" height="3.6"/>
|
||||
<rect x="1.2" y="8" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -6.5181 3.8275)" class="st1" width="0.3" height="3.6"/>
|
||||
<rect x="1.2" y="13.7" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -10.5305 5.4895)" class="st1" width="0.3" height="3.6"/>
|
||||
<rect x="1.2" y="12.2" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -9.4952 5.0607)" class="st1" width="0.3" height="3.6"/>
|
||||
<rect x="1.2" y="17.9" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -13.5076 6.7227)" class="st1" width="0.3" height="3.6"/>
|
||||
<rect x="1.2" y="16.4" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -12.4724 6.2938)" class="st1" width="0.3" height="3.6"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
1
src/assets/img/equipment-item-background04.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 151 38"><defs><style>.cls-1,.cls-5{fill:#b3e8f4;}.cls-1{opacity:0;}.cls-2{fill:#83beed;}.cls-3{fill:#dff3fa;}.cls-4{fill:#fcfefd;}.cls-6{fill:#fde9f2;}</style></defs><path class="cls-1" d="M140.66,2H4.17A4.17,4.17,0,0,0,0,6.15v21.5l10.6,10.6H147.09a4.17,4.17,0,0,0,4.17-4.17V12.59Z"/><path class="cls-2" d="M147.09,36.29H11.41L2,26.84V6.15A2.21,2.21,0,0,1,4.17,3.94H139.85l9.45,9.46V34.08A2.21,2.21,0,0,1,147.09,36.29ZM11.52,36H147.09a2,2,0,0,0,2-2V13.5l-9.31-9.31H4.17a2,2,0,0,0-2,2V26.73Z"/><polygon class="cls-3" points="24.78 5.81 8.01 5.81 11.16 2.33 27.93 2.33 24.78 5.81"/><polygon class="cls-4" points="137.13 36.16 127.56 36.16 129.36 34.17 138.93 34.17 137.13 36.16"/><polygon class="cls-4" points="114.9 36.16 105.33 36.16 107.13 34.17 116.7 34.17 114.9 36.16"/><polygon class="cls-4" points="92.67 36.16 83.11 36.16 84.91 34.17 94.47 34.17 92.67 36.16"/><polygon class="cls-5" points="123.2 6.35 92.68 6.35 98.42 0 128.94 0 123.2 6.35"/><rect class="cls-4" x="77.43" y="33.96" width="71.74" height="0.25"/><polygon id="_13" data-name="13" class="cls-6" points="138.62 8.13 139.09 11.2 142.16 11.67 139.09 12.14 138.62 15.21 138.15 12.14 135.08 11.67 138.15 11.2 138.62 8.13"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/assets/img/equipment-item-background05.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 151 38"><defs><style>.cls-1{fill:#fff;opacity:0.05;}.cls-2{fill:#af2334;opacity:0.75;}.cls-3{fill:#30c4c4;}.cls-4{fill:#dff3fa;}.cls-5{fill:#fcfefd;}</style></defs><path class="cls-1" d="M140.18,2H3.68A4.17,4.17,0,0,0-.48,6.15v21.5l10.6,10.6H146.61a4.17,4.17,0,0,0,4.17-4.17V12.59Z"/><path class="cls-2" d="M140.18,2H3.68A4.17,4.17,0,0,0-.48,6.15v21.5l10.6,10.6H146.61a4.17,4.17,0,0,0,4.17-4.17V12.59Z"/><path class="cls-3" d="M146.61,36.29H10.93L1.47,26.84V6.15A2.22,2.22,0,0,1,3.68,3.94H139.36l9.46,9.46V34.08A2.21,2.21,0,0,1,146.61,36.29ZM11,36H146.61a2,2,0,0,0,2-2V13.5l-9.31-9.31H3.68a2,2,0,0,0-2,2V26.73Z"/><polygon class="cls-4" points="24.3 5.81 7.53 5.81 10.68 2.33 27.45 2.33 24.3 5.81"/><polygon class="cls-5" points="136.65 36.16 127.08 36.16 128.88 34.17 138.45 34.17 136.65 36.16"/><polygon class="cls-5" points="114.42 36.16 104.85 36.16 106.65 34.17 116.22 34.17 114.42 36.16"/><polygon class="cls-5" points="92.19 36.16 82.62 36.16 84.42 34.17 93.99 34.17 92.19 36.16"/><polygon class="cls-4" points="122.72 6.35 92.2 6.35 97.94 0 128.45 0 122.72 6.35"/><rect class="cls-5" x="76.95" y="33.96" width="71.74" height="0.25"/></svg>
|
After Width: | Height: | Size: 1.2 KiB |
1
src/assets/img/equipment/replay01.svg
Normal file
After Width: | Height: | Size: 7.6 KiB |
1
src/assets/img/equipment/replay02.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12.66 12.66"><defs><style>.cls-1{opacity:0.8;}.cls-2{fill:#35eded;}.cls-3{fill:#ffe448;}</style></defs><g class="cls-1"><path class="cls-2" d="M4.89.76a5.87,5.87,0,0,0-1.48.62L2.87.84l-2,2,.54.54A5.87,5.87,0,0,0,.76,4.89H0V6.14H2.25A4.07,4.07,0,0,1,6.14,2.25V0H4.89Z"/><path class="cls-2" d="M10.41,6.51a4.09,4.09,0,0,1-3.9,3.9v2.25H7.76v-.77a5.57,5.57,0,0,0,1.49-.61l.54.54,2-2-.54-.54a5.57,5.57,0,0,0,.61-1.49h.77V6.51Z"/></g><g class="cls-1"><path class="cls-3" d="M2.25,6.51H0V7.76H.76a5.94,5.94,0,0,0,.62,1.49l-.54.54,2,2,.54-.54a5.5,5.5,0,0,0,1.48.61v.77H6.14V10.41A4.08,4.08,0,0,1,2.25,6.51Z"/><path class="cls-3" d="M11.89,4.89a5.5,5.5,0,0,0-.61-1.48l.54-.54-2-2-.54.54A5.94,5.94,0,0,0,7.76.76V0H6.51V2.25a4.08,4.08,0,0,1,3.9,3.89h2.25V4.89Z"/></g></svg>
|
After Width: | Height: | Size: 850 B |
1
src/assets/img/equipment/state-background.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13.73 25.44"><defs><style>.cls-1{opacity:0.8;}.cls-2{fill:#64ed81;}</style></defs><g class="cls-1"><path class="cls-2" d="M2.52,4.79A2.4,2.4,0,0,1,2.52,0,2.42,2.42,0,0,1,4.84,1.79h8.89V3H4.84A2.42,2.42,0,0,1,2.52,4.79Zm0-4.54A2.15,2.15,0,1,0,4.61,2.84l0-.09h8.84V2H4.64l0-.1A2.15,2.15,0,0,0,2.52.25Zm0,3.58A1.44,1.44,0,1,1,4,2.39,1.44,1.44,0,0,1,2.52,3.83Zm0-2.62A1.19,1.19,0,1,0,3.71,2.39,1.18,1.18,0,0,0,2.52,1.21Z"/><path class="cls-2" d="M2.48,11.67a2.4,2.4,0,1,1,2.32-3h8.9V9.88H4.8A2.41,2.41,0,0,1,2.48,11.67Zm0-4.54a2.15,2.15,0,1,0,2.1,2.6l0-.1h8.85V8.92H4.6l0-.09A2.16,2.16,0,0,0,2.48,7.13Zm0,3.59A1.44,1.44,0,1,1,3.92,9.28,1.44,1.44,0,0,1,2.48,10.72Zm0-2.63A1.19,1.19,0,1,0,3.67,9.28,1.18,1.18,0,0,0,2.48,8.09Z"/><path class="cls-2" d="M2.43,18.55a2.39,2.39,0,1,1,2.31-3h8.9v1.2H4.74A2.4,2.4,0,0,1,2.43,18.55Zm0-4.53a2.14,2.14,0,1,0,2.09,2.59l0-.1h8.85v-.7H4.54l0-.1A2.15,2.15,0,0,0,2.43,14Zm0,3.58a1.44,1.44,0,1,1,1.44-1.44A1.45,1.45,0,0,1,2.43,17.6Zm0-2.63a1.19,1.19,0,0,0,0,2.38,1.19,1.19,0,1,0,0-2.38Z"/><path class="cls-2" d="M2.39,25.44a2.4,2.4,0,1,1,2.32-3H13.6v1.21H4.71A2.41,2.41,0,0,1,2.39,25.44Zm0-4.54a2.15,2.15,0,1,0,2.1,2.59l0-.09h8.84v-.71H4.51l0-.1A2.15,2.15,0,0,0,2.39,20.9Zm0,3.58A1.44,1.44,0,1,1,3.83,23,1.43,1.43,0,0,1,2.39,24.48Zm0-2.63A1.19,1.19,0,1,0,3.58,23,1.19,1.19,0,0,0,2.39,21.85Z"/></g></svg>
|
After Width: | Height: | Size: 1.4 KiB |
1
src/assets/img/equipment/state-title.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44.63 9.62"><defs><style>.cls-1{opacity:0.8;}.cls-2{fill:#35eded;}.cls-3{fill:#64ed81;}</style></defs><g class="cls-1"><rect class="cls-2" y="7.2" width="44.63" height="0.5"/></g><rect class="cls-3" x="34.71" y="4.68" width="9.62" height="0.25"/><rect class="cls-3" x="39.4" width="0.25" height="9.62"/></svg>
|
After Width: | Height: | Size: 397 B |
7
src/assets/img/equipment/table-item-w.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16.1 11.6" style="enable-background:new 0 0 16.1 11.6;" xml:space="preserve">
|
||||
|
||||
<polygon class="st0" fill="currentColor" points="0,11.6 10.3,11.6 16.1,5.8 10.3,0 0,0 5.8,5.8 "/>
|
||||
</svg>
|
After Width: | Height: | Size: 460 B |
1
src/assets/img/item-data-left-2.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 14 55"><defs><style>.cls-1{isolation:isolate;}.cls-2{mix-blend-mode:screen;opacity:0.75;}.cls-3{fill:#58bfe8;}</style></defs><g class="cls-1"><g id="圖層_1" data-name="圖層 1"><image class="cls-2" width="14" height="55" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAA3CAYAAAA8PXu0AAAACXBIWXMAAAsSAAALEgHS3X78AAAA8ElEQVRIS+2WTQrCMBBGX4roQhDcieAZvP9VPICIKxGyUKtx4Zc6TXVQF67yQZjm52Xarl5IKfFLRsU8FNUm2WrBRvOJqoUTcAHOqimDQYfnwBKYai1ptMAR2KtebMeJoLXA7nbgJChqtGXHqUYEdqo3nh0jcMW8aoYDj047YKPDN/rf2MLwr+bviYIOAvNeV0swbyQBeQzSvFr8JBV0UkEnFXRSQScVdFJBJxV08n/wla5kUWroX+x6jlWzmdZKs+rZIzzFaAwstFa63MAerYpFHh1XfGCPaHOr53e+2tljME7e8IUhh0Lmf3LywaaXO0TIazwsXqhCAAAAAElFTkSuQmCC"/><polygon class="cls-3" points="10.59 51.05 3.9 51.05 3.86 3.77 10.55 3.77 10.55 4.77 4.86 4.77 4.9 50.05 10.59 50.05 10.59 51.05"/></g></g></svg>
|
After Width: | Height: | Size: 926 B |
1
src/assets/img/item-data-left.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 14 55"><defs><style>.cls-1{isolation:isolate;}.cls-2{mix-blend-mode:screen;opacity:0.75;}.cls-3{fill:#23c8cc;}</style></defs><g class="cls-1"><g id="圖層_1" data-name="圖層 1"><image class="cls-2" width="14" height="55" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAA3CAYAAAA8PXu0AAAACXBIWXMAAAsSAAALEgHS3X78AAAA8ElEQVRIS+2WTQrCMBBGX4roQhDcieAZvP9VPICIKxGyUKtx4Zc6TXVQF67yQZjm52Xarl5IKfFLRsU8FNUm2WrBRvOJqoUTcAHOqimDQYfnwBKYai1ptMAR2KtebMeJoLXA7nbgJChqtGXHqUYEdqo3nh0jcMW8aoYDj047YKPDN/rf2MLwr+bviYIOAvNeV0swbyQBeQzSvFr8JBV0UkEnFXRSQScVdFJBJxV08n/wla5kUWroX+x6jlWzmdZKs+rZIzzFaAwstFa63MAerYpFHh1XfGCPaHOr53e+2tljME7e8IUhh0Lmf3LywaaXO0TIazwsXqhCAAAAAElFTkSuQmCC"/><polygon class="cls-3" points="10.59 51.05 3.9 51.05 3.86 3.77 10.55 3.77 10.55 4.77 4.86 4.77 4.9 50.05 10.59 50.05 10.59 51.05"/></g></g></svg>
|
After Width: | Height: | Size: 926 B |
1
src/assets/img/item-data-right-2.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 14 55"><defs><style>.cls-1{isolation:isolate;}.cls-2{mix-blend-mode:screen;opacity:0.75;}.cls-3{fill:#58bfe8;}</style></defs><g class="cls-1"><g id="圖層_1" data-name="圖層 1"><image class="cls-2" width="14" height="55" transform="matrix(-1, 0, 0, 1, 14, 0)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAA3CAYAAAA8PXu0AAAACXBIWXMAAAsSAAALEgHS3X78AAAA8ElEQVRIS+2WTQrCMBBGX4roQhDcieAZvP9VPICIKxGyUKtx4Zc6TXVQF67yQZjm52Xarl5IKfFLRsU8FNUm2WrBRvOJqoUTcAHOqimDQYfnwBKYai1ptMAR2KtebMeJoLXA7nbgJChqtGXHqUYEdqo3nh0jcMW8aoYDj047YKPDN/rf2MLwr+bviYIOAvNeV0swbyQBeQzSvFr8JBV0UkEnFXRSQScVdFJBJxV08n/wla5kUWroX+x6jlWzmdZKs+rZIzzFaAwstFa63MAerYpFHh1XfGCPaHOr53e+2tljME7e8IUhh0Lmf3LywaaXO0TIazwsXqhCAAAAAElFTkSuQmCC"/><polygon class="cls-3" points="3.41 51.05 10.1 51.05 10.14 3.77 3.44 3.77 3.44 4.77 9.14 4.77 9.1 50.05 3.41 50.05 3.41 51.05"/></g></g></svg>
|
After Width: | Height: | Size: 962 B |
1
src/assets/img/item-data-right.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 14 55"><defs><style>.cls-1{isolation:isolate;}.cls-2{mix-blend-mode:screen;opacity:0.75;}.cls-3{fill:#23c8cc;}</style></defs><g class="cls-1"><g id="圖層_1" data-name="圖層 1"><image class="cls-2" width="14" height="55" transform="matrix(-1, 0, 0, 1, 14, 0)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAA3CAYAAAA8PXu0AAAACXBIWXMAAAsSAAALEgHS3X78AAAA8ElEQVRIS+2WTQrCMBBGX4roQhDcieAZvP9VPICIKxGyUKtx4Zc6TXVQF67yQZjm52Xarl5IKfFLRsU8FNUm2WrBRvOJqoUTcAHOqimDQYfnwBKYai1ptMAR2KtebMeJoLXA7nbgJChqtGXHqUYEdqo3nh0jcMW8aoYDj047YKPDN/rf2MLwr+bviYIOAvNeV0swbyQBeQzSvFr8JBV0UkEnFXRSQScVdFJBJxV08n/wla5kUWroX+x6jlWzmdZKs+rZIzzFaAwstFa63MAerYpFHh1XfGCPaHOr53e+2tljME7e8IUhh0Lmf3LywaaXO0TIazwsXqhCAAAAAElFTkSuQmCC"/><polygon class="cls-3" points="3.41 51.05 10.1 51.05 10.14 3.77 3.44 3.77 3.44 4.77 9.14 4.77 9.1 50.05 3.41 50.05 3.41 51.05"/></g></g></svg>
|
After Width: | Height: | Size: 962 B |
BIN
src/assets/img/logo.png
Normal file
After Width: | Height: | Size: 40 KiB |
1
src/assets/img/logo.svg
Normal file
After Width: | Height: | Size: 122 KiB |
14
src/assets/img/pagination/small-btn.svg
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24.4 19.5" style="enable-background:new 0 0 24.4 19.5;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{opacity:0.6;}
|
||||
.st1{fill:#83FF97;}
|
||||
</style>
|
||||
<g class="st0">
|
||||
<g>
|
||||
<path class="st1" d="M17.5,19.5H0l6.8-9.8L0,0h17.5l6.8,9.8l-0.1,0.1L17.5,19.5z M1,19h16.3l6.5-9.3l-6.5-9.3H1l6.5,9.3L1,19z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 595 B |
9
src/assets/img/pagination/small-btn02.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24.4 19.5" style="enable-background:new 0 0 24.4 19.5;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{opacity:0.6;fill:#83FF97;}
|
||||
</style>
|
||||
<polygon class="st0" points="17.5,0 0,0 6.8,9.8 0,19.5 17.5,19.5 24.3,9.9 24.4,9.8 "/>
|
||||
</svg>
|
After Width: | Height: | Size: 514 B |
BIN
src/assets/img/state-box-bottom.png
Normal file
After Width: | Height: | Size: 722 B |
BIN
src/assets/img/state-box-top.png
Normal file
After Width: | Height: | Size: 713 B |
1
src/assets/img/state-title01.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8"><defs><style>.cls-1{fill:#ffe422;}</style></defs><polygon id="_13" data-name="13" class="cls-1" points="4 0.19 4.5 3.5 7.81 4 4.5 4.5 4 7.81 3.5 4.5 0.19 4 3.5 3.5 4 0.19"/></svg>
|
After Width: | Height: | Size: 272 B |
1
src/assets/img/state-title02.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 9"><defs><style>.cls-1{fill:#30c4c4;}</style></defs><path id="_12" data-name="12" class="cls-1" d="M22,4.44C21.92,4.4,8.63,4,7.59,3.11A11.13,11.13,0,0,1,4.82.19h-1A9.65,9.65,0,0,1,0,4V5a9.65,9.65,0,0,1,3.8,3.8h1a11.12,11.12,0,0,1,2.7-3.1C8.17,5.17,21.94,4.59,22,4.56Z"/></svg>
|
After Width: | Height: | Size: 367 B |
1
src/assets/img/state-ul-background01.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4.91 37.93"><defs><style>.cls-1{opacity:0.8;}.cls-2{fill:#ffe422;}</style></defs><g id="_70" data-name="70" class="cls-1"><rect class="cls-2" x="2.21" y="29.6" width="0.49" height="6.45" transform="translate(-22.5 11.35) rotate(-45)"/><rect class="cls-2" x="2.21" y="32.24" width="0.49" height="6.45" transform="translate(-24.36 12.13) rotate(-45)"/><rect class="cls-2" x="2.21" y="22.01" width="0.49" height="6.45" transform="translate(-17.13 9.13) rotate(-45)"/><rect class="cls-2" x="2.21" y="24.65" width="0.49" height="6.45" transform="translate(-18.99 9.9) rotate(-45)"/><rect class="cls-2" x="2.21" y="14.42" width="0.49" height="6.45" transform="translate(-11.76 6.9) rotate(-45)"/><rect class="cls-2" x="2.21" y="17.06" width="0.49" height="6.45" transform="translate(-13.62 7.68) rotate(-45)"/><rect class="cls-2" x="2.21" y="6.82" width="0.49" height="6.45" transform="translate(-6.39 4.68) rotate(-45)"/><rect class="cls-2" x="2.21" y="9.46" width="0.49" height="6.45" transform="translate(-8.25 5.45) rotate(-45)"/><rect class="cls-2" x="2.21" y="-0.77" width="0.49" height="6.45" transform="translate(-1.02 2.46) rotate(-45)"/><rect class="cls-2" x="2.21" y="1.87" width="0.49" height="6.45" transform="translate(-2.88 3.23) rotate(-45)"/></g></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/assets/img/state-ul-background02.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 7.13 78.94"><defs><style>.cls-1{fill:#fde9f2;}</style></defs><g id="_67" data-name="67"><rect class="cls-1" y="75.13" width="3.57" height="3.57"/><rect class="cls-1" y="68" width="3.57" height="3.57"/><rect class="cls-1" y="60.87" width="3.57" height="3.57"/><rect class="cls-1" y="53.73" width="3.57" height="3.57"/><rect class="cls-1" y="46.6" width="3.57" height="3.57"/><rect class="cls-1" y="39.47" width="3.57" height="3.57"/><rect class="cls-1" y="32.34" width="3.57" height="3.57"/><rect class="cls-1" y="25.2" width="3.57" height="3.57"/><rect class="cls-1" y="18.07" width="3.57" height="3.57"/><rect class="cls-1" y="10.94" width="3.57" height="3.57"/><rect class="cls-1" y="3.81" width="3.57" height="3.57"/><rect class="cls-1" x="3.57" y="71.56" width="3.57" height="3.57"/><rect class="cls-1" x="3.57" y="64.43" width="3.57" height="3.57"/><rect class="cls-1" x="3.57" y="57.3" width="3.57" height="3.57"/><rect class="cls-1" x="3.57" y="50.17" width="3.57" height="3.57"/><rect class="cls-1" x="3.57" y="43.03" width="3.57" height="3.57"/><rect class="cls-1" x="3.57" y="35.9" width="3.57" height="3.57"/><rect class="cls-1" x="3.57" y="28.77" width="3.57" height="3.57"/><rect class="cls-1" x="3.57" y="21.64" width="3.57" height="3.57"/><rect class="cls-1" x="3.57" y="14.51" width="3.57" height="3.57"/><rect class="cls-1" x="3.57" y="7.37" width="3.57" height="3.57"/><rect class="cls-1" x="3.57" y="0.24" width="3.57" height="3.57"/></g></svg>
|
After Width: | Height: | Size: 1.5 KiB |
1
src/assets/img/state-ul-text.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 9"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M22.56,4.36h-8a3,3,0,0,0-2.87-2.88V.4h-.29V1.48A3,3,0,0,0,8.49,4.36h-8v.28H8.49a3,3,0,0,0,2.87,2.88V8.6h.29V7.52a3,3,0,0,0,2.87-2.88h8ZM13.44,2.57a2.73,2.73,0,0,1,.8,1.79H12.38a.89.89,0,0,0-.73-.74V1.77A2.7,2.7,0,0,1,13.44,2.57Zm-3.87,0a2.7,2.7,0,0,1,1.79-.8V3.62a.88.88,0,0,0-.73.74H8.77A2.73,2.73,0,0,1,9.57,2.57Zm0,3.87a2.76,2.76,0,0,1-.8-1.8h1.86a.88.88,0,0,0,.73.74V7.23A2.74,2.74,0,0,1,9.57,6.44Zm3.87,0a2.74,2.74,0,0,1-1.79.79V5.38a.89.89,0,0,0,.73-.74h1.86A2.76,2.76,0,0,1,13.44,6.44Z"/></svg>
|
After Width: | Height: | Size: 664 B |
49
src/assets/img/state-ul.svg
Normal file
@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 110.8 43.5" style="enable-background:new 0 0 110.8 43.5;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{opacity:0.5;fill:url(#SVGID_1_);}
|
||||
.st1{fill:#FFFFFF;}
|
||||
.st2{opacity:0.7;}
|
||||
.st3{fill:#79AECC;}
|
||||
.st4{fill:#DFF3FA;}
|
||||
</style>
|
||||
<g>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="6.0326" y1="21.8344" x2="106.0948" y2="21.8344">
|
||||
<stop offset="0" style="stop-color:#0CA9D4;stop-opacity:0.7"/>
|
||||
<stop offset="2.671185e-02" style="stop-color:#27ABD7;stop-opacity:0.6626"/>
|
||||
<stop offset="6.063062e-02" style="stop-color:#42AEDA;stop-opacity:0.6151"/>
|
||||
<stop offset="9.965897e-02" style="stop-color:#58B0DC;stop-opacity:0.5605"/>
|
||||
<stop offset="0.1452" style="stop-color:#69B1DE;stop-opacity:0.4967"/>
|
||||
<stop offset="0.2015" style="stop-color:#74B2DF;stop-opacity:0.4178"/>
|
||||
<stop offset="0.2806" style="stop-color:#7BB3E0;stop-opacity:0.3072"/>
|
||||
<stop offset="0.5" style="stop-color:#7DB3E0;stop-opacity:0"/>
|
||||
<stop offset="0.7194" style="stop-color:#7BB3E0;stop-opacity:0.3072"/>
|
||||
<stop offset="0.7985" style="stop-color:#74B2DF;stop-opacity:0.4178"/>
|
||||
<stop offset="0.8548" style="stop-color:#69B1DE;stop-opacity:0.4967"/>
|
||||
<stop offset="0.9003" style="stop-color:#58B0DC;stop-opacity:0.5605"/>
|
||||
<stop offset="0.9394" style="stop-color:#42AEDA;stop-opacity:0.6151"/>
|
||||
<stop offset="0.9733" style="stop-color:#27ABD7;stop-opacity:0.6626"/>
|
||||
<stop offset="1" style="stop-color:#0CA9D4;stop-opacity:0.7"/>
|
||||
</linearGradient>
|
||||
<path class="st0" d="M104.6,39.6H7.5c-0.8,0-1.5-0.7-1.5-1.5V5.5c0-0.8,0.7-1.5,1.5-1.5h97.1c0.8,0,1.5,0.7,1.5,1.5v32.6
|
||||
C106.1,38.9,105.4,39.6,104.6,39.6z"/>
|
||||
<g>
|
||||
<path class="st1" d="M102.5,38H9.6c-0.8,0-1.5-0.7-1.5-1.5V7.1c0-0.8,0.7-1.5,1.5-1.5h92.9c0.8,0,1.5,0.7,1.5,1.5v29.5
|
||||
C104,37.4,103.3,38,102.5,38z M9.6,5.9c-0.7,0-1.2,0.5-1.2,1.2v29.5c0,0.7,0.5,1.2,1.2,1.2h92.9c0.7,0,1.2-0.5,1.2-1.2V7.1
|
||||
c0-0.7-0.5-1.2-1.2-1.2H9.6z"/>
|
||||
</g>
|
||||
<g class="st2">
|
||||
<g>
|
||||
<path class="st3" d="M107,43.4H5.1c-2.4,0-4.4-2-4.4-4.4V4.6c0-2.4,2-4.4,4.4-4.4H107c2.4,0,4.4,2,4.4,4.4V39
|
||||
C111.4,41.5,109.4,43.4,107,43.4z M5.1,2.3c-1.3,0-2.4,1.1-2.4,2.4V39c0,1.3,1.1,2.4,2.4,2.4H107c1.3,0,2.4-1.1,2.4-2.4V4.6
|
||||
c0-1.3-1.1-2.4-2.4-2.4H5.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
<polygon class="st4" points="66.5,3.1 44,3.1 45.7,0.2 68.1,0.2 "/>
|
||||
<polygon class="st4" points="66.5,43.4 44,43.4 45.7,40.6 68.1,40.6 "/>
|
||||
<polygon class="st4" points="4.5,11.4 4.5,33.9 0.7,32.2 0.7,9.8 "/>
|
||||
<polygon class="st4" points="111.4,11.4 111.4,33.9 107.6,32.2 107.6,9.8 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
44
src/assets/img/table/content-box-background01.svg
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 9.7 11.1" style="enable-background:new 0 0 9.7 11.1;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#3BBBC9;}
|
||||
.st1{fill:#3B69B1;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<rect y="0" class="st0" width="1" height="0.8"/>
|
||||
<rect y="2.1" class="st0" width="1" height="0.8"/>
|
||||
<rect y="4.1" class="st0" width="1" height="0.8"/>
|
||||
<rect y="6.2" class="st0" width="1" height="0.8"/>
|
||||
<rect y="8.2" class="st0" width="1" height="0.8"/>
|
||||
<rect y="10.3" class="st0" width="1" height="0.8"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="1.7" y="0" class="st1" width="1" height="0.8"/>
|
||||
<rect x="1.7" y="2.1" class="st1" width="1" height="0.8"/>
|
||||
<rect x="1.7" y="4.1" class="st1" width="1" height="0.8"/>
|
||||
<rect x="1.7" y="6.2" class="st1" width="1" height="0.8"/>
|
||||
<rect x="1.7" y="8.2" class="st1" width="1" height="0.8"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="3.6" class="st0" width="1" height="0.8"/>
|
||||
<rect x="3.6" y="2.1" class="st0" width="1" height="0.8"/>
|
||||
<rect x="3.6" y="4.1" class="st0" width="1" height="0.8"/>
|
||||
<rect x="3.6" y="6.2" class="st0" width="1" height="0.8"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="5.4" class="st1" width="1" height="0.8"/>
|
||||
<rect x="5.4" y="2.1" class="st1" width="1" height="0.8"/>
|
||||
<rect x="5.4" y="4.1" class="st1" width="1" height="0.8"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="7.1" y="0" class="st0" width="1" height="0.8"/>
|
||||
<rect x="7.1" y="2.1" class="st0" width="1" height="0.8"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="8.7" class="st1" width="1" height="0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
43
src/assets/img/table/content-box-background02.svg
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 12 12" style="enable-background:new 0 0 12 12;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{clip-path:url(#SVGID_00000139282756432431693520000014554874042273548179_);fill:#041725;}
|
||||
.st1{clip-path:url(#SVGID_00000139282756432431693520000014554874042273548179_);}
|
||||
.st2{clip-path:url(#SVGID_00000180351338875884756140000007490444363737273490_);}
|
||||
.st3{opacity:0.8;fill:#35EDED;enable-background:new ;}
|
||||
.st4{fill:#35EDED;}
|
||||
</style>
|
||||
<g>
|
||||
<defs>
|
||||
<polygon id="SVGID_1_" points="0,6 6.1,12 12,12 12,0 0,0 "/>
|
||||
</defs>
|
||||
<clipPath id="SVGID_00000108283119261920149820000010393207167217912208_">
|
||||
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
|
||||
</clipPath>
|
||||
<rect style="clip-path:url(#SVGID_00000108283119261920149820000010393207167217912208_);fill:#041725;" width="12" height="12"/>
|
||||
<g style="clip-path:url(#SVGID_00000108283119261920149820000010393207167217912208_);">
|
||||
<g>
|
||||
<defs>
|
||||
<rect id="SVGID_00000118377240633176785250000005727722924531941272_" y="1.9" width="11" height="10.1"/>
|
||||
</defs>
|
||||
<clipPath id="SVGID_00000117676141971077797980000001536752723917697420_">
|
||||
<use xlink:href="#SVGID_00000118377240633176785250000005727722924531941272_" style="overflow:visible;"/>
|
||||
</clipPath>
|
||||
<g style="clip-path:url(#SVGID_00000117676141971077797980000001536752723917697420_);">
|
||||
<path class="st3" d="M16.5,256.3c-1.2-0.9-2.4-0.2-2.6,0.8H8v26.3h-792.4l-5.7-5.7v-4.5l0,0v-1.3h-4.1v1.3h3.4v4.7l6.1,6.1H-0.5
|
||||
l1.7,2.8h10.1v-8.4l-2.7-1.8v-18.9h5.3c0.2,0.7,0.8,1.2,1.5,1.2C16.6,259,17.5,257.6,16.5,256.3z M15.4,258.4
|
||||
c-0.5,0-0.9-0.4-0.9-0.9s0.4-0.9,0.9-0.9s0.9,0.4,0.9,0.9S15.9,258.4,15.4,258.4z"/>
|
||||
<polyline class="st3" points="0.8,4.7 8,11.8 8,250.1 8.6,250.1 8.6,11.5 1.1,4 "/>
|
||||
<polyline class="st3" points="1.1,4 -790.8,4 -790.8,261.5 -794.2,261.5 -794.2,262.7 -790.1,262.7 -790.1,261.5 -790.1,261.5
|
||||
-790.1,4.7 0.8,4.7 "/>
|
||||
<rect x="-794.2" y="269.8" class="st4" width="4.1" height="1.2"/>
|
||||
<rect x="-794.2" y="267.7" class="st4" width="4.1" height="1.2"/>
|
||||
<rect x="-794.2" y="265.6" class="st4" width="4.1" height="1.2"/>
|
||||
<rect x="-794.2" y="263.6" class="st4" width="4.1" height="1.2"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
43
src/assets/img/table/content-box-background03.svg
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 9.8 23.2" style="enable-background:new 0 0 9.8 23.2;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{clip-path:url(#SVGID_00000162336351291435253000000011369610487883135147_);fill:#041725;}
|
||||
.st1{clip-path:url(#SVGID_00000162336351291435253000000011369610487883135147_);}
|
||||
.st2{clip-path:url(#SVGID_00000179646246557638455150000007031289474206077343_);}
|
||||
.st3{opacity:0.8;fill:#35EDED;enable-background:new ;}
|
||||
.st4{fill:#35EDED;}
|
||||
</style>
|
||||
<g>
|
||||
<defs>
|
||||
<polygon id="SVGID_1_" points="6,-0.1 6,14.8 9.8,19.3 9.9,23.2 0,23.2 0,-0.1 "/>
|
||||
</defs>
|
||||
<clipPath id="SVGID_00000069365692663666114570000004382809312686603691_">
|
||||
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
|
||||
</clipPath>
|
||||
|
||||
<rect x="-0.3" y="-0.1" style="clip-path:url(#SVGID_00000069365692663666114570000004382809312686603691_);fill:#041725;" width="10.2" height="23.3"/>
|
||||
<g style="clip-path:url(#SVGID_00000069365692663666114570000004382809312686603691_);">
|
||||
<g>
|
||||
<defs>
|
||||
<rect id="SVGID_00000069391242059943023700000011095916327524102832_" x="-0.3" width="10.2" height="23.2"/>
|
||||
</defs>
|
||||
<clipPath id="SVGID_00000076592079320817103330000010913419046470824587_">
|
||||
<use xlink:href="#SVGID_00000069391242059943023700000011095916327524102832_" style="overflow:visible;"/>
|
||||
</clipPath>
|
||||
<g style="clip-path:url(#SVGID_00000076592079320817103330000010913419046470824587_);">
|
||||
<path class="st3" d="M810.7-5.2c-1.2-0.9-2.4-0.2-2.6,0.8h-5.9v26.3H9.8l-5.7-5.7v-4.5l0,0v-1.3H0v1.3h3.4v4.7l6.1,6.1h784.2
|
||||
l1.7,2.8h10.1v-8.4l-2.7-1.8V-3.8h5.3c0.2,0.7,0.8,1.2,1.5,1.2C810.8-2.5,811.7-3.9,810.7-5.2z M809.6-3.2
|
||||
c-0.5,0-0.9-0.4-0.9-0.9s0.4-0.9,0.9-0.9s0.9,0.4,0.9,0.9S810.1-3.2,809.6-3.2z"/>
|
||||
<polygon class="st3" points="4.1,-0.1 4.1,-0.1 4.1,-256.9 795,-256.9 802.2,-249.8 802.2,-11.5 802.8,-11.5 802.8,-250
|
||||
795.3,-257.6 3.4,-257.6 3.4,-0.1 0,-0.1 0,1.2 4.1,1.2 "/>
|
||||
<rect y="8.3" class="st4" width="4.1" height="1.2"/>
|
||||
<rect y="6.2" class="st4" width="4.1" height="1.2"/>
|
||||
<rect y="4.1" class="st4" width="4.1" height="1.2"/>
|
||||
<rect y="2" class="st4" width="4.1" height="1.2"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
38
src/assets/img/table/content-box-background04.svg
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 17.7 36.8" style="enable-background:new 0 0 17.7 36.8;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{clip-path:url(#SVGID_00000014592019429068395720000011308713662110083751_);fill:#041725;}
|
||||
.st1{clip-path:url(#SVGID_00000014592019429068395720000011308713662110083751_);}
|
||||
.st2{clip-path:url(#SVGID_00000139268676221631833710000004672253205110111671_);}
|
||||
.st3{opacity:0.8;fill:#35EDED;enable-background:new ;}
|
||||
</style>
|
||||
<g>
|
||||
<defs>
|
||||
<polygon id="SVGID_1_" points="0,29.7 4.9,29.7 4.9,0.1 17.7,0.1 17.7,36.9 0,36.9 "/>
|
||||
</defs>
|
||||
<clipPath id="SVGID_00000146475346453478477000000018158311794988225670_">
|
||||
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
|
||||
</clipPath>
|
||||
|
||||
<rect y="0.1" style="clip-path:url(#SVGID_00000146475346453478477000000018158311794988225670_);fill:#041725;" width="17.7" height="36.8"/>
|
||||
<g style="clip-path:url(#SVGID_00000146475346453478477000000018158311794988225670_);">
|
||||
<g>
|
||||
<defs>
|
||||
<rect id="SVGID_00000181088581726856941440000011579023093141653907_" y="0.1" width="17.7" height="36.8"/>
|
||||
</defs>
|
||||
<clipPath id="SVGID_00000064336413382373671560000002740350498911710124_">
|
||||
<use xlink:href="#SVGID_00000181088581726856941440000011579023093141653907_" style="overflow:visible;"/>
|
||||
</clipPath>
|
||||
<g style="clip-path:url(#SVGID_00000064336413382373671560000002740350498911710124_);">
|
||||
<path class="st3" d="M17.3,6.3c-1.2-0.9-2.4-0.2-2.6,0.8h-6v26.3h-792.4l-5.7-5.7v-4.5l0,0v-1.3h-4.1v1.3h3.4V28l6.1,6.1H0.3
|
||||
L2,36.8h10.1v-8.4l-2.7-1.8V7.8h5.3C14.8,8.5,15.4,9,16.2,9C17.4,9,18.3,7.6,17.3,6.3z M16.2,8.4c-0.5,0-0.9-0.4-0.9-0.9
|
||||
s0.4-0.9,0.9-0.9s0.9,0.4,0.9,0.9S16.7,8.4,16.2,8.4z"/>
|
||||
<polygon class="st3" points="-789.3,11.5 -789.3,11.5 -789.3,-245.3 1.6,-245.3 8.8,-238.2 8.8,0.1 9.4,0.1 9.4,-238.4
|
||||
1.9,-246 -790,-246 -790,11.5 -793.4,11.5 -793.4,12.7 -789.3,12.7 "/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
44
src/assets/img/table/content-box-background05.svg
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 9.7 11.1" style="enable-background:new 0 0 9.7 11.1;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#3BBBC9;}
|
||||
.st1{fill:#3B69B1;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<rect x="8.7" y="10.3" class="st0" width="1" height="0.8"/>
|
||||
<rect x="8.7" y="8.2" class="st0" width="1" height="0.8"/>
|
||||
<rect x="8.7" y="6.2" class="st0" width="1" height="0.8"/>
|
||||
<rect x="8.7" y="4.1" class="st0" width="1" height="0.8"/>
|
||||
<rect x="8.7" y="2.1" class="st0" width="1" height="0.8"/>
|
||||
<rect x="8.7" y="0" class="st0" width="1" height="0.8"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="7" y="10.3" class="st1" width="1" height="0.8"/>
|
||||
<rect x="7" y="8.2" class="st1" width="1" height="0.8"/>
|
||||
<rect x="7" y="6.2" class="st1" width="1" height="0.8"/>
|
||||
<rect x="7" y="4.1" class="st1" width="1" height="0.8"/>
|
||||
<rect x="7" y="2.1" class="st1" width="1" height="0.8"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="5.1" y="10.3" class="st0" width="1" height="0.8"/>
|
||||
<rect x="5.1" y="8.2" class="st0" width="1" height="0.8"/>
|
||||
<rect x="5.1" y="6.2" class="st0" width="1" height="0.8"/>
|
||||
<rect x="5.1" y="4.1" class="st0" width="1" height="0.8"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="3.3" y="10.3" class="st1" width="1" height="0.8"/>
|
||||
<rect x="3.3" y="8.2" class="st1" width="1" height="0.8"/>
|
||||
<rect x="3.3" y="6.2" class="st1" width="1" height="0.8"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="1.6" y="10.3" class="st0" width="1" height="0.8"/>
|
||||
<rect x="1.6" y="8.2" class="st0" width="1" height="0.8"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="0" y="10.3" class="st1" width="1" height="0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
18
src/assets/img/table/large-btn.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 36.7 19.5" style="enable-background:new 0 0 36.7 19.5;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{opacity:0.6;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
.st2{fill:#83FF97;}
|
||||
</style>
|
||||
<g class="st0">
|
||||
<g>
|
||||
<polygon class="st1" points="0.5,19.3 29.7,19.3 36.4,9.8 29.7,0.2 0.5,0.2 7.1,9.8 "/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st2" d="M29.8,19.5H0l6.8-9.8L0,0h29.8l6.8,9.8L29.8,19.5z M1,19h28.6l6.5-9.3l-6.5-9.3H1l6.5,9.3L1,19z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 708 B |
14
src/assets/img/table/large-btn02.svg
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 36.7 19.5" style="enable-background:new 0 0 36.7 19.5;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{opacity:0.6;}
|
||||
.st1{fill:#83FF97;}
|
||||
</style>
|
||||
<g class="st0">
|
||||
<g>
|
||||
<path class="st1" d="M29.8,19.5H0l6.8-9.8L0,0h29.8l6.8,9.8l-0.1,0.1L29.8,19.5z M1,19h28.6l6.5-9.3l-6.5-9.3H1l6.5,9.3L1,19z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 595 B |
14
src/assets/img/table/small-btn.svg
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24.4 19.5" style="enable-background:new 0 0 24.4 19.5;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{opacity:0.6;}
|
||||
.st1{fill:#83FF97;}
|
||||
</style>
|
||||
<g class="st0">
|
||||
<g>
|
||||
<path class="st1" d="M17.5,19.5H0l6.8-9.8L0,0h17.5l6.8,9.8l-0.1,0.1L17.5,19.5z M1,19h16.3l6.5-9.3l-6.5-9.3H1l6.5,9.3L1,19z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 595 B |
9
src/assets/img/table/small-btn02.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24.4 19.5" style="enable-background:new 0 0 24.4 19.5;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{opacity:0.6;fill:#83FF97;}
|
||||
</style>
|
||||
<polygon class="st0" points="17.5,0 0,0 6.8,9.8 0,19.5 17.5,19.5 24.3,9.9 24.4,9.8 "/>
|
||||
</svg>
|
After Width: | Height: | Size: 514 B |
1
src/assets/img/text-position-line.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 111 7"><defs><style>.cls-1{fill:#5eabea;}.cls-2{fill:#d0032c;}</style></defs><path id="_66" data-name="66" class="cls-1" d="M55.74,7.19A3.7,3.7,0,0,1,59.37,4l51.39-.45L59.37,3.15A3.7,3.7,0,0,1,55.74,0Z"/><path id="_66-2" data-name="66" class="cls-2" d="M55.74,0h0a3.7,3.7,0,0,1-3.63,3.15L0,3.59,52.11,4a3.7,3.7,0,0,1,3.63,3.15Z"/></svg>
|
After Width: | Height: | Size: 424 B |
81
src/assets/index.css
Normal file
@ -0,0 +1,81 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
.arrow {
|
||||
@apply relative triangle flex justify-center items-center text-lg;
|
||||
box-shadow: inset 0px 6px 10px -10px rgba(255, 255, 255, 0.8),
|
||||
inset 0px -6px 10px -10px rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.triangle {
|
||||
@apply after:block after:absolute after:bottom-0 after:left-[100%]
|
||||
after:border-t-[1rem] after:border-b-[1rem] after:border-l-[2rem]
|
||||
after:border-t-transparent after:border-b-transparent after:z-50;
|
||||
}
|
||||
.triangle-dark {
|
||||
@apply after:border-l-info;
|
||||
}
|
||||
|
||||
.triangle-light {
|
||||
@apply after:border-l-success;
|
||||
}
|
||||
.item button {
|
||||
@apply hover:bg-active !important;
|
||||
}
|
||||
/* table */
|
||||
.content-box-background {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(127, 237, 193, 0.1),
|
||||
rgba(0, 0, 0, 0),
|
||||
rgba(127, 237, 193, 0.1)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.btn{
|
||||
@apply whitespace-nowrap px-4 py-1;
|
||||
text-shadow: 0px 0px 5px rgba(0, 0, 0, 0.9);
|
||||
box-shadow: 0px 0px 5px rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
@apply text-white border border-active bg-active hover:bg-[theme("colors.green.500")]
|
||||
}
|
||||
|
||||
.btn-info {
|
||||
@apply text-white border border-info bg-info hover:bg-[theme("colors.sky.400")]
|
||||
}
|
||||
|
||||
.btn-outline-success {
|
||||
@apply text-white border border-active hover:bg-active bg-transparent
|
||||
}
|
||||
|
||||
.btn-outline-info {
|
||||
@apply text-white border border-info hover:bg-info bg-transparent
|
||||
}
|
||||
|
||||
.custom-border {
|
||||
@apply border border-info rounded-md;
|
||||
}
|
||||
|
||||
.btn-text-without-border {
|
||||
@apply active:border-0 focus:border-0 focus-visible:border-0 active:outline-none focus:outline-none focus-visible:outline-none;
|
||||
}
|
||||
|
||||
.btn-add {
|
||||
@apply text-white border border-cyan-400 bg-cyan-400 hover:bg-[theme("colors.cyan.500")]
|
||||
}
|
||||
|
||||
.btn-search {
|
||||
@apply text-white border border-sky-400 bg-sky-400 hover:bg-[theme("colors.sky.500")]
|
||||
}
|
||||
|
||||
.btn-export {
|
||||
@apply text-white border border-emerald-400 bg-emerald-400 hover:bg-[theme("colors.emerald.500")]
|
||||
}
|
||||
|
||||
}
|
1
src/assets/logo.svg
Normal file
After Width: | Height: | Size: 150 KiB |
29
src/assets/main.css
Normal file
@ -0,0 +1,29 @@
|
||||
@import "./base.css";
|
||||
|
||||
#app {
|
||||
overflow: hidden;
|
||||
font-weight: normal;
|
||||
background-color: theme("colors.body");
|
||||
background-image: url("./img/background.jpg");
|
||||
background-size: cover;
|
||||
color: #fff;
|
||||
min-height: 100dvh;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 5px !important;
|
||||
height: 8px !important;
|
||||
}
|
||||
|
||||
/* Track */
|
||||
::-webkit-scrollbar-track {
|
||||
box-shadow: inset 0 0 5px grey;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
/* Handle */
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: theme("colors.info");
|
||||
border-radius: 10px;
|
||||
box-shadow: theme("boxShadow.custom");
|
||||
}
|
40
src/assets/pagination.css
Normal file
@ -0,0 +1,40 @@
|
||||
.page-box ul {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
flex-wrap: wrap;
|
||||
font-size: 1rem;
|
||||
color: #fff;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.page-box ul li {
|
||||
padding: 10px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
.page-box ul .ant-pagination-item {
|
||||
background-image: url(./img/pagination/small-btn.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
padding: 10px 15px 10px 25px;
|
||||
background-color: transparent;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.page-box ul .ant-pagination-item.ant-pagination-item-active {
|
||||
background-image: url(./img/pagination/small-btn02.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
padding: 10px 15px 10px 25px;
|
||||
}
|
||||
|
||||
.page-box .ant-pagination-item a {
|
||||
color: #fff;
|
||||
}
|
122
src/assets/table.css
Normal file
@ -0,0 +1,122 @@
|
||||
/**資料框**/
|
||||
.ant-table {
|
||||
width: 100%;
|
||||
margin-bottom: 1rem;
|
||||
background-color: transparent !important;
|
||||
color: white;
|
||||
}
|
||||
.ant-table::-webkit-scrollbar-thumb {
|
||||
background-color: theme("colors.info") !important;
|
||||
}
|
||||
|
||||
.ant-table th.ant-table-cell::before{
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.content-box {
|
||||
border: 1px solid #35eded;
|
||||
padding: 5px;
|
||||
position: relative;
|
||||
margin-bottom: 15px;
|
||||
background-color: theme("colors.body");
|
||||
}
|
||||
|
||||
.content-box table,
|
||||
.content-box table th {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.content-box .ant-table th.ant-table-cell,
|
||||
.content-box .ant-table td.ant-table-cell {
|
||||
border-color: #fff !important;
|
||||
color: #fff !important;
|
||||
font-size: 1rem !important;
|
||||
font-weight: 300 !important;
|
||||
border-right: 1px solid #fff !important;
|
||||
text-align: center !important;
|
||||
padding: 0.5rem 0.75rem !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.content-box .ant-table th.ant-table-cell.ant-table-cell-fix-left,
|
||||
.content-box .ant-table th.ant-table-cell.ant-table-cell-fix-right {
|
||||
background-color: theme("colors.body") !important;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.content-box .ant-table th.ant-table-cell {
|
||||
border-bottom: 1px solid #e9e9e9 !important;
|
||||
}
|
||||
|
||||
.content-box .ant-table tr td:last-child,
|
||||
.content-box .ant-table tr:first-child th:last-child {
|
||||
border-right: 0 !important;
|
||||
}
|
||||
.content-box .ant-table tr:last-child td {
|
||||
border-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/**資料框裝飾**/
|
||||
.content-box::before {
|
||||
content: "" !important;
|
||||
background: url(./img/table/content-box-background01.svg) center center !important;
|
||||
position: absolute !important;
|
||||
left: 4px !important;
|
||||
top: 4px !important;
|
||||
height: 20px !important;
|
||||
width: 20px !important;
|
||||
background-repeat: no-repeat !important;
|
||||
z-index: 1 !important;
|
||||
}
|
||||
|
||||
.content-box::after {
|
||||
content: "" !important;
|
||||
background: url(./img/table/content-box-background05.svg) center center !important;
|
||||
position: absolute !important;
|
||||
right: 4px !important;
|
||||
bottom: 4px !important;
|
||||
height: 20px !important;
|
||||
width: 20px !important;
|
||||
background-repeat: no-repeat !important;
|
||||
z-index: 3 !important;
|
||||
}
|
||||
|
||||
.content-box .page-box::before {
|
||||
content: "" !important;
|
||||
background: url(./img/table/content-box-background03.svg) center center !important;
|
||||
position: absolute !important;
|
||||
left: -1.2% !important;
|
||||
bottom: -2px !important;
|
||||
height: 56px !important;
|
||||
width: 30px !important;
|
||||
background-repeat: no-repeat !important;
|
||||
z-index: 2 !important;
|
||||
}
|
||||
|
||||
.content-box .page-box::after {
|
||||
content: "" !important;
|
||||
background: url(./img/table/content-box-background04.svg) center center !important;
|
||||
position: absolute !important;
|
||||
right: -27px !important;
|
||||
bottom: -7px !important;
|
||||
height: 65px !important;
|
||||
width: 50px !important;
|
||||
background-repeat: no-repeat !important;
|
||||
z-index: 2 !important;
|
||||
}
|
||||
|
||||
.content-box .content-decoration {
|
||||
@apply px-2;
|
||||
}
|
||||
|
||||
.content-box .content-decoration::before {
|
||||
content: "" !important;
|
||||
background: url(./img/table/content-box-background02.svg) center center !important;
|
||||
position: absolute !important;
|
||||
right: -10px !important;
|
||||
top: -10px !important;
|
||||
height: 30px !important;
|
||||
width: 29px !important;
|
||||
background-repeat: no-repeat !important;
|
||||
z-index: 1 !important;
|
||||
}
|
32
src/components/Loading.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<script setup></script>
|
||||
|
||||
<template>
|
||||
<div class="w-full h-full flex items-center justify-center">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="css" scoped>
|
||||
.loader {
|
||||
width: 20%;
|
||||
height: 22px;
|
||||
border-radius: 20px;
|
||||
color: theme(colors.success);
|
||||
border: 2px solid theme(colors.success);
|
||||
position: relative;
|
||||
}
|
||||
.loader::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
margin: 2px;
|
||||
inset: 0 100% 0 0;
|
||||
border-radius: inherit;
|
||||
background: currentColor;
|
||||
animation: l6 2s infinite;
|
||||
}
|
||||
@keyframes l6 {
|
||||
100% {
|
||||
inset: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
44
src/components/SvgIcon.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<i :style="getStyle">
|
||||
<svg :class="class" aria-hidden="true">
|
||||
<use :xlink:href="symbolId" :stroke="color" :fill="color" />
|
||||
</svg>
|
||||
</i>
|
||||
</template>
|
||||
|
||||
<script setup name="SvgIcon">
|
||||
import { computed } from 'vue'
|
||||
const props = defineProps({
|
||||
prefix: {
|
||||
type: String,
|
||||
default: 'icon',
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: 'transparent',
|
||||
},
|
||||
size: {
|
||||
type: [Number, String],
|
||||
default: 10,
|
||||
},
|
||||
class: {
|
||||
type: String,
|
||||
default: "w-10 h-10",
|
||||
},
|
||||
})
|
||||
|
||||
const symbolId = computed(() => `#${props.prefix}-${props.name}`)
|
||||
const getStyle = computed(() => {
|
||||
const { size } = props
|
||||
let s = `${size}`
|
||||
s = `${s.replace('px', '')}px`
|
||||
return {
|
||||
fontSize: s,
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
87
src/components/alarm/AlarmCards.vue
Normal file
@ -0,0 +1,87 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
import { getAlertLog } from "@/apis/alert";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const dataSource = ref([]);
|
||||
let intervalId = null; // 用來儲存 setInterval 的 ID
|
||||
|
||||
const getAlarmData = async () => {
|
||||
const res = await getAlertLog({
|
||||
isRecovery: 1,
|
||||
Start_date: dayjs().format("YYYY-MM-DD"),
|
||||
End_date: dayjs().format("YYYY-MM-DD"),
|
||||
});
|
||||
dataSource.value = (res.data || []).map((d) => ({ ...d, key: d.id }));
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getAlarmData();
|
||||
|
||||
intervalId = setInterval(() => {
|
||||
getAlarmData();
|
||||
}, 30 * 1000);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
intervalId = null;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<ul class="pr-4 min-h-full text-base-content">
|
||||
<!-- Sidebar content here -->
|
||||
<li class="my-3" v-for="alarm in dataSource" :key="alarm.id">
|
||||
<div
|
||||
class="w-full shadow-xl border border-success bg-body bg-opacity-80"
|
||||
>
|
||||
<div class="p-5">
|
||||
<p class="text-base flex justify-between">
|
||||
<span>
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'exclamation-triangle']"
|
||||
class="text-warning mr-2"
|
||||
/>
|
||||
<span>{{ $t("alarm.notify") }}</span></span
|
||||
>
|
||||
<small>
|
||||
<span class="mr-4"
|
||||
>{{ alarm.created_at }}</span
|
||||
>
|
||||
<!-- <font-awesome-icon
|
||||
:icon="['fas', 'times']"
|
||||
size="lg"
|
||||
class="text-white"
|
||||
/> -->
|
||||
</small>
|
||||
</p>
|
||||
<div class="divider my-2"></div>
|
||||
<div>
|
||||
<p>{{ $t("alarm.number") }}:{{ alarm.id }}</p>
|
||||
<p>{{ $t("alert.alarmClass") }}:{{ alarm.factor }}</p>
|
||||
<p>{{ $t("alarm.device_name") }}:{{ alarm.device_number }}</p>
|
||||
<p>{{ $t("alert.device_point_name") }}:{{ alarm.points }}</p>
|
||||
<p>{{ $t("alert.error_msg") }}:{{ alarm.reason }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card::before {
|
||||
@apply absolute h-5 w-5 top-1 left-1 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background01.svg')] bg-center;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.card::after {
|
||||
@apply absolute bottom-1 right-1 h-5 w-5 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background05.svg')] bg-center;
|
||||
content: "";
|
||||
}
|
||||
</style>
|
51
src/components/alarm/AlarmDrawer.vue
Normal file
@ -0,0 +1,51 @@
|
||||
<script setup>
|
||||
import { onMounted, ref } from "vue";
|
||||
import AlarmCards from "./AlarmCards.vue";
|
||||
|
||||
const showErr = ref(false);
|
||||
const toggleErrIcon = () => {
|
||||
console.log("Toggle");
|
||||
showErr.value = !showErr.value;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="drawer drawer-end">
|
||||
<input id="alarm" type="checkbox" class="drawer-toggle" />
|
||||
<div class="drawer-content">
|
||||
<!-- Page content here -->
|
||||
<label
|
||||
for="alarm"
|
||||
class="drawer-button flex flex-col justify-center items-center bg-transparent text-white"
|
||||
@click="toggleErrIcon"
|
||||
>
|
||||
<font-awesome-icon
|
||||
v-if="!showErr"
|
||||
:icon="['fas', 'comment-dots']"
|
||||
class="text-lg lg:text-2xl mb-1"
|
||||
/>
|
||||
<font-awesome-icon
|
||||
v-else
|
||||
:icon="['fas', 'comment-slash']"
|
||||
class="text-lg lg:text-2xl mb-1"
|
||||
/>
|
||||
<span class="text-xs lg:text-sm block"> {{ $t("alarm.title") }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
v-if="showErr"
|
||||
class="drawer-side translate-y-20 max-h-[90vh] overflow-x-hidden overflow-y-scroll"
|
||||
>
|
||||
<AlarmCards />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.drawer-toggle,
|
||||
.drawer-button {
|
||||
outline: none !important;
|
||||
outline-offset: 0 !important;
|
||||
border: 0 !important;
|
||||
}
|
||||
</style>
|
57
src/components/chart/BarChart.vue
Normal file
@ -0,0 +1,57 @@
|
||||
<script setup>
|
||||
import * as echarts from "echarts";
|
||||
import { onMounted, ref, markRaw, watch, onBeforeUnmount } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
option: Object, // 圖表配置選項
|
||||
class: String, // 類名
|
||||
id: String, // 圖表ID
|
||||
});
|
||||
|
||||
let chart = ref(null); // 用於儲存圖表實例
|
||||
let dom = ref(null); // 用於儲存DOM元素引用
|
||||
|
||||
// 初始化圖表的函數
|
||||
function init() {
|
||||
if (dom.value) {
|
||||
let echart = echarts;
|
||||
chart.value = markRaw(echart.init(dom.value)); // 初始化圖表
|
||||
chart.value.setOption(props.option); // 設定初始選項
|
||||
}
|
||||
}
|
||||
|
||||
// 當組件掛載完成後初始化圖表
|
||||
onMounted(() => {
|
||||
if (!chart.value && dom.value) {
|
||||
init();
|
||||
}
|
||||
});
|
||||
|
||||
// 監聽 props.option 的變化,重新設置圖表選項
|
||||
watch(
|
||||
() => props.option,
|
||||
(newOption) => {
|
||||
if (chart.value) {
|
||||
chart.value.setOption(newOption); // 更新圖表選項
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// 當組件卸載時銷毀圖表,防止內存洩漏
|
||||
onBeforeUnmount(() => {
|
||||
if (chart.value) {
|
||||
chart.value.dispose(); // 銷毀圖表實例
|
||||
}
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
chart, // 對外暴露 chart 變量
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :id="id" :class="class" ref="dom" style="height: 100%; width: 100%;"></div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
83
src/components/chart/EffectScatter.vue
Normal file
@ -0,0 +1,83 @@
|
||||
<script setup>
|
||||
import * as echarts from "echarts";
|
||||
import { onMounted, ref, markRaw } from "vue";
|
||||
import axios from "axios";
|
||||
|
||||
const props = defineProps({
|
||||
option: Object,
|
||||
className: String,
|
||||
id: String,
|
||||
svg: Object,
|
||||
getCoordinate: {
|
||||
type: Function,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
let chart = ref(null);
|
||||
let dom = ref(null);
|
||||
let currentClickPosition = ref([]);
|
||||
|
||||
async function updateSvg(svg, option) {
|
||||
if (!chart.value && dom.value && svg) {
|
||||
init();
|
||||
} else {
|
||||
clear();
|
||||
}
|
||||
axios.get(svg.path).then(({ data }) => {
|
||||
echarts.registerMap(svg.full_name, { svg: data });
|
||||
chart.value.setOption(option);
|
||||
if (props.getCoordinate) {
|
||||
chart.value.getZr().on("click", function (params) {
|
||||
var pixelPoint = [params.offsetX, params.offsetY];
|
||||
var dataPoint = chart.value.convertFromPixel(
|
||||
{ geoIndex: 0 },
|
||||
pixelPoint
|
||||
);
|
||||
currentClickPosition.value = dataPoint;
|
||||
props.getCoordinate(dataPoint);
|
||||
const updatedData = option.series.data
|
||||
.filter(
|
||||
(point) => !(point.itemStyle && point.itemStyle.color === "#0000FF")
|
||||
)
|
||||
.concat({
|
||||
value: dataPoint, // 當前座標值
|
||||
itemStyle: { color: "#0000FF" }, // 設為藍色
|
||||
});
|
||||
chart.value.setOption({
|
||||
series: {
|
||||
data: updatedData,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
console.log("updateSvg", svg.path);
|
||||
}
|
||||
|
||||
function clear() {
|
||||
chart.value.clear();
|
||||
}
|
||||
|
||||
function init() {
|
||||
const curChart = echarts.init(dom.value);
|
||||
chart.value = markRaw(curChart);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (!chart.value && dom.value && props.svg) {
|
||||
init();
|
||||
}
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
chart,
|
||||
currentClickPosition,
|
||||
updateSvg,
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div :id="id" class="min-h-full max-h-fit w-full" ref="dom"></div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
34
src/components/chart/GaugeChart.vue
Normal file
@ -0,0 +1,34 @@
|
||||
<script setup>
|
||||
import * as echarts from "echarts";
|
||||
import { onMounted, ref, markRaw } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
option: Object,
|
||||
class: String,
|
||||
id: String,
|
||||
});
|
||||
|
||||
let chart = ref(null);
|
||||
let dom = ref(null);
|
||||
|
||||
function init() {
|
||||
let echart = echarts;
|
||||
chart.value = markRaw(echart.init(dom.value));
|
||||
chart.value.setOption(props.option);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (!chart.value && dom.value) {
|
||||
init();
|
||||
}
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
chart,
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div :id="id" :class="class" ref="dom"></div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|