feat: 算力配置和设备现场交互完成

dev-deviceSetting
donghao 1 year ago
parent b2538ee9ef
commit 8eabf8c471

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-12 14:35:28
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-01-24 11:33:27
* @LastEditTime: 2024-03-21 17:55:12
* @FilePath: \General-AI-Platform-Web-Client\index.html
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
@ -21,8 +21,9 @@
<!-- update 2024-01-21 16:41 -->
<link
rel="stylesheet"
href="//at.alicdn.com/t/c/font_4412653_g3j0o4m1zi.css"
href="//at.alicdn.com/t/c/font_4412653_eop55bznk7u.css"
/>
<script src="https://threejs.org/build/three.js"></script>
<script>
window.process = {};

@ -25,6 +25,7 @@ buttons:
menus:
hshome: 工作台
hsdevice: 设备列表
hsdeviceScene: 设备现场
hsModelList: 模型列表
hsserver: 服务器
hstest: 测试

@ -0,0 +1,45 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-17 13:54:43
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-03-20 14:50:57
* @FilePath: \General-AI-Platform-Web-Client\mock\alarm.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { MockMethod } from "vite-plugin-mock";
import {
deviceSceneListData,
deviceSceneItemsData
} from "./pools/deviceSceneData";
import {
fetchCurrPageByList,
fetchMockSuccessFullByOther
} from "./utils/apiMock";
export default [
{
url: "/getDeviceSceneList",
method: "post",
response: () => {
return fetchMockSuccessFullByOther({ data: deviceSceneListData.data });
}
},
{
url: "/getDeviceSceneItemsList",
method: "post",
response: req => {
const { page, pageSize } = req.body;
// console.log(req);
return {
...fetchCurrPageByList({
...deviceSceneItemsData,
data: {
...deviceSceneItemsData.data,
page,
pageSize: pageSize || 10
}
})
};
}
}
] as MockMethod[];

@ -0,0 +1,62 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-02-22 13:38:04
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-03-20 16:51:18
* @FilePath: \General-AI-Platform-Web-Client\mock\pools\alarmData.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { generateRandomDateTimeByYear } from "../utils/mockMoment";
function fetchSceneItemsList(args = { maxCount: 24 }): Record<string, any>[] {
const { maxCount } = args;
const currList: Record<string, any>[] = [];
const productTypeArr = ["工件9501", "工件1132", "工件2108", "工件9183"];
for (let i = 0; i < maxCount; i++) {
currList.push({
id: 10000 + i,
alarmNo: 24031215050 + (i + 1), // 序号
defectType: "表面裂纹", // 缺陷类型
createTime: generateRandomDateTimeByYear(2024),
updateTime: "2023-10-17T02:35:41.14308Z", // 检测时间
productType:
productTypeArr[Math.floor(Math.random() * productTypeArr.length)], //产品类型
productL: "15.8mm", // 长
productW: "15.8mm" // 宽
// baseInfo: {
// left: 397.0215, // 相对x
// top: 444.5797 // 相对y
// }
});
}
return currList;
}
function fetchList(): Record<string, any>[] {
const currList: Record<string, any>[] = [];
for (let i = 0; i < 2; i++) {
currList.push({
id: 1 + i,
createTime: generateRandomDateTimeByYear(2023),
updateTime: "2023-10-17T02:35:41.14308Z",
name: "GigEPRO_gmcam_01_00" + (i + 1),
alarmList: fetchSceneItemsList({ maxCount: 3 })
});
}
return currList;
}
export const deviceSceneListData = {
data: fetchList()
};
export const deviceSceneItemsData = {
data: {
list: fetchSceneItemsList(),
total: fetchSceneItemsList().length,
page: 1,
pageSize: 10
}
};

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-15 14:45:56
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-03-07 17:14:04
* @LastEditTime: 2024-03-20 14:26:49
* @FilePath: \General-AI-Platform-Web-Client\src\api\list.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
@ -52,3 +52,11 @@ export const getPowerPoolsList = (data?: object) => {
export const getPowerGroupList = (data?: object) => {
return http.request<Result>("post", "/getPowerGroupList", { data });
};
/**设备现场 */
export const getDeviceSceneList = (data?: object) => {
return http.request<Result>("post", "/getDeviceSceneList", { data });
};
export const getDeviceSceneItemsList = (data?: object) => {
return http.request<Result>("post", "/getDeviceSceneItemsList", { data });
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

@ -2,14 +2,14 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-02-23 11:38:23
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-03-08 13:54:01
* @LastEditTime: 2024-03-18 10:05:39
* @FilePath: \General-AI-Platform-Web-Client\src\components\DsBox\index.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import dsBox1 from "./src/dsBox1";
import dsBox2 from "./src/dsBox2";
import dsTag1 from "./src/dsTag1";
import dsTag2 from "./src/dsTag2";
import dsTag2 from "./src/dsTag1";
export const DsBox1 = dsBox1;
export const DsBox2 = dsBox2;

@ -224,4 +224,8 @@ const layoutHeader = defineComponent({
background-color: transparent !important;
}
}
.deviceScene_page {
background: #fcfcfc;
}
</style>

@ -0,0 +1,23 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-03-19 15:44:27
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-03-20 15:50:20
* @FilePath: \General-AI-Platform-Web-Client\src\router\modules\deviceScene.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { $t } from "@/plugins/i18n";
export default {
path: "/deviceScene",
meta: {
title: $t("menus.hsdeviceScene"),
icon: "icon-shebeiliebiao-weixuan",
// showLink: false,
bodyClass: "deviceScene_page",
rank: 7,
roles: ["admin", "common"]
},
component: () => import("@/views/device/scene.vue"),
name: "DeviceScene"
} as RouteConfigsTable;

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-19 09:38:33
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-03-08 14:53:53
* @LastEditTime: 2024-03-12 14:20:00
* @FilePath: \General-AI-Platform-Web-Client\src\views\demo\cube.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
@ -82,7 +82,6 @@ const fetchPathValByHeight = val => {
height: 20px;
background: url("@/assets/computePower/tipIcon.svg") no-repeat;
background-size: cover;
// tipIcon.svg
}
.bg_body_logo {
/* width: 358.886px;

@ -0,0 +1,102 @@
.deviceScene_wrap {
.deviceScene_container {
.deviceScene_body {
.scene_box {
background-color: white;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
.left {
width: 65.52%;
padding: 16px 48px;
.deviceScene_box_top {
font-weight: bold;
font-size: 16px;
color: #333333;
padding: 8px 0 16px;
.bg_icon {
color: #154ddd;
i {
font-size: 25px;
}
margin-right: 14px;
}
}
}
.right {
width: 32.61%;
.alarm_head {
padding: 7px 16px;
border-bottom: 1px solid #e0e0e0;
.label {
font-weight: bold;
font-size: 16px;
color: #333333;
}
}
.alarm_body {
& > li {
background: #f3f6ff;
margin: 16px;
border-radius: 2px;
h5 {
padding: 12px;
border-bottom: 1px solid #e0e0e0;
font-weight: bold;
font-size: 14px;
color: #333333;
}
.alarm_info {
font-weight: 500;
font-size: 14px;
padding: 12px;
color: #666666;
& > p {
padding-bottom: 8px;
}
.label {
}
.active_value {
color: #e80d0d;
}
}
}
}
}
}
}
.el-dialog__body {
padding-top: 8px;
}
.alarm_table {
height: 550px;
}
.alarm_detail_box {
.alarm_detail_info {
border-radius: 2px;
h5 {
padding: 0 0 12px;
font-weight: bold;
font-size: 14px;
color: #333333;
}
.alarm_info {
font-weight: 500;
font-size: 14px;
color: #666666;
& > p {
padding-bottom: 8px;
}
.label {
}
.active_value {
color: #e80d0d;
}
}
}
}
}

@ -0,0 +1,406 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-03-19 15:35:17
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-03-21 17:57:17
* @FilePath: \General-AI-Platform-Web-Client\src\views\device\scene.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script setup lang="ts">
import { onMounted, ref, reactive, h } from "vue";
import { getDeviceSceneList, getDeviceSceneItemsList } from "@/api/list";
import type { FormInstance } from "element-plus";
import { fabric } from "fabric";
import { BaseTable } from "@/components/CustomTable";
import jiankongtu1 from "@/assets/device/jiankongtu1.png";
defineOptions({
name: "DeviceScene"
});
const formData = ref({
deviceSort: "",
deviceSceneItem: ""
});
const dataLoading = ref<boolean>(true);
// alarmDataLoading
const alarmDataLoading = ref<boolean>(true);
const isShowFull = ref<boolean>(false);
const listData = ref<Record<string, any>[]>([]);
const currDeviceSceneItems = ref<Record<string, any>[]>([]);
const alarmListData = ref<Record<string, any>[]>([]);
const canvasRef = ref<any>(null);
const cvs = ref<any>(null);
const clipPathData = ref<{
width: number;
height: number;
}>({
width: 740, //
height: 474 //
});
const svg = `
<path class="path" d="
M 30 15
L 28 17
M 25.61 25.61
A 15 15, 0, 0, 1, 15 30
A 15 15, 0, 1, 1, 27.99 7.5
L 15 15
" style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
`;
const pagination = ref({ currentPage: 1, pageSize: 8, total: 0 });
const formRef = ref<FormInstance>();
const alarmValidateForm = reactive({
defectType: "",
createTime: ""
});
const isShowAlarmDatail = ref<boolean>(false);
const currRowData = ref<Record<string, any>>({});
const columns = [
{
label: "序号",
property: "alarmNo"
},
{
label: "产品类型",
property: "productType"
},
{
label: "缺陷类型",
property: "defectType",
formatter: val => {
return h(
"div",
{
style: {
color: "#e80d0d",
fontSize: "12px"
}
},
val.defectType
);
}
},
{
label: "生产日期",
property: "createTime"
},
{
type: "action",
label: "操作"
}
];
//
const getList = async () => {
const { data } = await getDeviceSceneList();
listData.value = data;
formData.value = {
...formData.value,
deviceSceneItem: data[0].name
};
currDeviceSceneItems.value = data[0].alarmList;
initCanvas();
dataLoading.value = false;
console.log(data, "getDeviceSceneList_data");
};
//
function initCanvas() {
const canvasObject = new fabric.Canvas(canvasRef.value);
canvasObject.setBackgroundImage(
jiankongtu1,
canvasObject.renderAll.bind(canvasObject),
{
width: clipPathData.value.width,
height: clipPathData.value.height,
originX: "left",
originY: "top"
}
);
// canvasObject.loadFromJSON(JSON.stringify(currJson), () => {
// canvasObject.renderAll();
// });
// const rect = new fabric.Rect({
// left: 100,
// top: 100,
// width: 200,
// height: 100,
// fill: "transparent", //
// stroke: "green", //
// strokeWidth: 3, //
// rx: 2, //
// ry: 2 //
// });
// // Canvas
// canvasObject.add(rect);
cvs.value = canvasObject;
console.log(canvasObject);
}
//
const getAlarmList = async () => {
const { currentPage, pageSize } = pagination.value;
const { data } = await getDeviceSceneItemsList({
page: currentPage,
pageSize
});
// listData.value = data;
alarmListData.value = data.list;
pagination.value = {
...pagination.value,
total: data.total
};
// formData.value = {
// ...formData.value,
// deviceSceneItem: data[0].name
// };
// currDeviceSceneItems.value = data[0].alarmList;
alarmDataLoading.value = false;
console.log(data, "getAlarmList_data");
};
const submitForm = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.validate(valid => {
if (valid) {
console.log("submit!");
} else {
console.log("error submit!");
return false;
}
});
};
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.resetFields();
};
function showFullAlert() {
isShowFull.value = true;
getAlarmList();
}
function handleDetail(rowData) {
isShowFull.value = false;
currRowData.value = rowData;
isShowAlarmDatail.value = true;
}
onMounted(() => {
getList();
});
</script>
<template>
<div class="deviceScene_wrap">
<div class="deviceScene_container" v-loading="dataLoading">
<div class="deviceScene_head">
<el-form :inline="true" :model="formData" class="demo-form-inline">
<el-form-item label="车间">
<el-select
v-model="formData.deviceSort"
placeholder="车间"
clearable
>
<el-option label="车间1" value="车间1" />
<el-option label="车间2" value="车间2" />
</el-select>
</el-form-item>
<el-form-item label="设备">
<el-select
v-model="formData.deviceSceneItem"
placeholder="设备"
clearable
>
<el-option
v-for="(v, k) in listData"
:label="v.name"
:value="v.name"
:key="k"
/>
</el-select>
</el-form-item>
</el-form>
</div>
<div class="flex justify-between deviceScene_body">
<div class="left scene_box">
<div class="flex items-center deviceScene_box_top">
<div class="bg_icon">
<i class="iconfont icon-jiwei"></i>
</div>
<span>机位</span><span>{{ formData.deviceSceneItem }}</span>
</div>
<canvas
ref="canvasRef"
:width="clipPathData.width"
:height="clipPathData.height"
/>
</div>
<div class="right scene_box">
<div class="flex items-center justify-between alarm_head">
<span class="label">缺陷告警</span>
<el-button type="primary" @click="showFullAlert"
>全部告警</el-button
>
</div>
<ul class="alarm_body">
<li v-for="(v, k) in currDeviceSceneItems" :key="k">
<h5>
<span class="label">序号: </span><span>{{ v.alarmNo }}</span>
</h5>
<div class="alarm_info">
<p>
<span class="label">缺陷类型: </span
><span class="active_value">{{ v.defectType }}</span>
</p>
<p>
<span class="label">检测时间: </span
><span>{{ v.createTime }}</span>
</p>
<div>
<span class="label">产品类型: </span
><span class="pr-[16px]">{{ v.productType }}</span>
<span class="label">: </span
><span class="pr-[16px]">{{ v.productL }}</span>
<span class="label">: </span
><span class="pr-[16px]">{{ v.productW }}</span>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<el-dialog
top="5vh"
v-model="isShowFull"
title="全部告警"
width="70vw"
:style="{
borderRadius: '6px'
}"
>
<div class="alarm_dialog_head">
<el-form
ref="formRef"
:inline="true"
:model="formData"
class="demo-form-inline"
>
<el-form-item label="缺陷类型">
<el-select
v-model="alarmValidateForm.defectType"
placeholder="缺陷类型"
clearable
>
<el-option label="表面裂纹" value="表面裂纹" />
<el-option label="划痕" value="划痕" />
</el-select>
</el-form-item>
<el-form-item label="生产日期">
<el-date-picker
v-model="alarmValidateForm.createTime"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
</el-form-item>
<el-form-item>
<el-button @click="resetForm(formRef)"></el-button>
<el-button type="primary" @click="submitForm(formRef)"
>查询</el-button
>
</el-form-item>
</el-form>
</div>
<div
class="alarm_table"
v-loading="alarmDataLoading"
:element-loading-svg="svg"
element-loading-svg-view-box="-10, -10, 50, 50"
>
<template v-if="pagination.total > 0">
<BaseTable
:total="pagination.total"
:pageSize="pagination.pageSize"
:dataSource="alarmListData"
:columns="columns"
:page="pagination.currentPage"
:isFixedPagination="false"
>
<template v-slot:actionBar="{ row }">
<ul class="table_action_box">
<li class="flex items-center" @click="handleDetail(row)">
<el-button text>
<span
:style="{
fontSize: '14px',
color: '#154DDD'
}"
>
查看详情
</span>
</el-button>
</li>
</ul>
</template>
</BaseTable>
</template>
</div>
</el-dialog>
<el-dialog
top="5vh"
v-model="isShowAlarmDatail"
title="缺陷报告"
:style="{
borderRadius: '6px'
}"
>
<div class="alarm_detail_box">
<div class="alarm_detail_info">
<h5>
<span class="label">序号: </span
><span>{{ currRowData.alarmNo }}</span>
</h5>
<div class="alarm_info">
<p>
<span class="label">缺陷类型: </span
><span class="active_value">{{ currRowData.defectType }}</span>
</p>
<p>
<span class="label">检测时间: </span
><span>{{ currRowData.createTime }}</span>
</p>
<p>
<span class="label">产品类型: </span
><span class="pr-[16px]">{{ currRowData.productType }}</span>
<span class="label">: </span
><span class="pr-[16px]">{{ currRowData.productL }}</span>
<span class="label">: </span
><span class="pr-[16px]">{{ currRowData.productW }}</span>
</p>
</div>
</div>
<img :src="jiankongtu1" />
</div>
</el-dialog>
</div>
</template>
<style lang="scss">
@import url("./scene.scss");
</style>
Loading…
Cancel
Save