diff --git a/src/assets/modelSetting/video_type_1.png b/src/assets/modelSetting/video_type_1.png new file mode 100644 index 0000000..beb4101 Binary files /dev/null and b/src/assets/modelSetting/video_type_1.png differ diff --git a/src/assets/modelSetting/video_type_2.png b/src/assets/modelSetting/video_type_2.png new file mode 100644 index 0000000..785c9d1 Binary files /dev/null and b/src/assets/modelSetting/video_type_2.png differ diff --git a/src/assets/modelSetting/video_type_3.png b/src/assets/modelSetting/video_type_3.png new file mode 100644 index 0000000..380ce74 Binary files /dev/null and b/src/assets/modelSetting/video_type_3.png differ diff --git a/src/views/deviceSetting/components/add.vue b/src/views/deviceSetting/components/add.vue index b7089ba..c157fac 100644 --- a/src/views/deviceSetting/components/add.vue +++ b/src/views/deviceSetting/components/add.vue @@ -2,7 +2,7 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2024-08-07 14:47:44 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2024-08-09 16:25:09 + * @LastEditTime: 2024-08-12 15:34:22 * @FilePath: \General-AI-Platform-Web-Client\src\views\deviceSetting\components\add.vue * @Description: 新建位置 --> @@ -20,6 +20,8 @@ const formData = ref({ name: "", file: null as File | null }); +const formRef = ref(null); + const dialogVisible = ref<boolean>(false); const fileList = ref([]); const rules = { @@ -55,7 +57,6 @@ const beforeUpload = (file: File) => { }; const submitForm = () => { - const formRef = form.value; formRef.validate((valid: boolean) => { if (valid) { message("提交成功", { type: "success" }); diff --git a/src/views/deviceSetting/components/deviceAttr.vue b/src/views/deviceSetting/components/deviceAttr.vue index f353365..cba63be 100644 --- a/src/views/deviceSetting/components/deviceAttr.vue +++ b/src/views/deviceSetting/components/deviceAttr.vue @@ -1,75 +1,64 @@ -<template> - <div class="box" v-if="mixinState.mSelectMode === 'one'"> - <!-- 字体属性 --> - <div v-show="textTypeConf.includes(mixinState.mSelectOneType)"> - <!-- 字体属性 --> - </div> - <!-- ID属性 --> - <div> - <div class="flex-view"> - <div class="flex-item"> - <span class="label">{{ $t("attributes.id") }}</span> - <div class="content slider-box"> - <input - v-model="baseAttr.id" - @change="changeCommon('id', baseAttr.id)" - /> - </div> - </div> - </div> - </div> - - <!-- 用户属性 --> - <!-- TODO 缺少删除 图标 --> - <div> - <ul> - <li class="flex-view" v-for="(v, k) in baseAttr.userProperty" :key="k"> - <div class="flex-item"> - <span class="content slider-box"> - <input - v-model="baseAttr.userProperty[k].key" - @change=" - changeCommon('userProperty_key', baseAttr.userProperty) - " - /> - </span> - <div class="content slider-box"> - <input - v-model="baseAttr.userProperty[k].value" - @change=" - changeCommon('userProperty_value', baseAttr.userProperty) - " - /> - </div> - </div> - </li> - <li - class="flex-view" - style="justify-content: center; color: dodgerblue; text-align: center" - @click=" - () => { - baseAttr.userProperty.push({ - key: 'key' + baseAttr.userProperty.length, - value: 'value' - }); - } - " - > - <span>新增一项</span> - </li> - </ul> - </div> - </div> -</template> - -<script setup name="AttrBute"> +<script setup lang="ts"> import useSelect from "@/hooks/select"; import { fetchArrayByAttrObject, setAttrObjectByArray } from "@/utils/utils"; // 属性选项 import { textTypeConf } from "@/config/attribute/baseType"; +import video_type_1 from "@/assets/modelSetting/video_type_1.png"; +import video_type_2 from "@/assets/modelSetting/video_type_2.png"; +import video_type_3 from "@/assets/modelSetting/video_type_3.png"; + const event = inject("event"); const update = getCurrentInstance(); const { mixinState, canvasEditor } = useSelect(); +/**业务属性 */ +const formData = ref({ + iconType: 1 +}); + +const rules = { + iconType: [{ required: true, message: "请选择图标类型", trigger: "change" }] +}; + +const iconOptions = ref([ + { + value: 1, + label: "图标1", + type: "1", + url: video_type_1 + }, + { + value: 2, + label: "图标2", + type: "2", + url: video_type_2 + }, + { + value: 3, + label: "图标3", + type: "3", + url: video_type_3 + } +]); +const formRef = ref(null); +const submitForm = () => { + formRef.value?.validate((valid: boolean) => { + if (valid) { + // 模拟提交接口 + // axios + // .post("/api/submit-icon", form.value) + // .then(() => { + // ElMessage.success("提交成功"); + // }) + // .catch(() => { + // ElMessage.error("提交失败"); + // }); + } else { + // ElMessage.error("表单验证失败"); + } + }); +}; + +/**拓展属性 */ // 通用属性 const baseAttr = reactive({ id: "", @@ -206,6 +195,58 @@ const changeCommon = (key, value) => { canvasEditor.canvas.renderAll(); return; } + if (key === "iconType") { + // 在 group 对象中查找唯一的 fabric.Image 对象 + const imageObject = activeObject._objects[1]; + + if (imageObject) { + const targetIcon = toRaw(iconOptions.value).find( + item => item.value === value + ); + console.log(targetIcon, "activeObject_iconType", activeObject); + + if (targetIcon) { + // 修改图片路径 + imageObject.setSrc( + targetIcon.url, + () => { + // 刷新画布 + console.log("Image loaded successfully activeObject_iconType"); + activeObject.addWithUpdate(); // 更新对象的坐标和边界框 + canvasEditor.canvas.renderAll(); + }, + { crossOrigin: "anonymous" } + ); + + // 加载新的图片并替换旧的图片对象 + // fabric.Image.fromURL( + // targetIcon.url, + // img => { + // // 使用 oldImage.get() 获取所有属性,并设置到新图片上 + // // img.set(imageObject.get()); + // // 在 group 中替换旧的图片对象 + // console.log(img, "old_img", imageObject); + // const index = activeObject._objects.indexOf(imageObject); + // if (index !== -1) { + // activeObject._objects[index] = { + // ...imageObject.get(), + // src: img.src + // }; // 替换为新的图片对象 + // activeObject.addWithUpdate(); // 更新 group 的边界和变换 + // canvasEditor.canvas.renderAll(); // 刷新画布 + // } else { + // console.error("Image object not found in the group."); + // } + // }, + // { + // crossOrigin: "anonymous" // 如果图片跨域需要设置 + // } + // ); + } + return; + } + return; + } activeObject && activeObject.set(key, value); canvasEditor.canvas.renderAll(); @@ -221,15 +262,90 @@ onBeforeUnmount(() => { canvasEditor.canvas.off("object:modified", getObjectAttr); }); </script> - -<style scoped> -.flex-view { - width: 100%; - margin-bottom: 5px; - padding: 5px; - display: inline-flex; - justify-content: space-between; - border-radius: 5px; - background: #f6f7f9; -} -</style> +<template> + <div class="box" v-if="mixinState.mSelectMode === 'one'"> + <!-- 字体属性 --> + <div v-show="textTypeConf.includes(mixinState.mSelectOneType)"> + <!-- 字体属性 --> + </div> + <!-- ID属性 --> + <!-- <div> + <div class="flex-view"> + <div class="flex-item"> + <span class="label">{{ $t("attributes.id") }}</span> + <div class="content slider-box"> + <input + v-model="baseAttr.id" + @change="changeCommon('id', baseAttr.id)" + /> + </div> + </div> + </div> + </div> --> + <el-form + ref="formRef" + :rules="rules" + :inline="true" + :model="formData" + class="demo-form-inline" + label-position="top" + > + <el-form-item label="选择图标" class="w-full" prop="iconType"> + <el-radio-group + v-model="formData.iconType" + @change="changeCommon('iconType', formData.iconType)" + > + <el-radio + v-for="option in iconOptions" + :key="option.value" + :label="option.value" + > + <i> + <!-- 图标 --> + </i> + {{ option.label }} + </el-radio> + </el-radio-group> + </el-form-item> + </el-form> + <!-- 动态属性 --> + <!-- <div> + <ul> + <li class="flex-view" v-for="(v, k) in baseAttr.userProperty" :key="k"> + <div class="flex-item"> + <span class="content slider-box"> + <input + v-model="baseAttr.userProperty[k].key" + @change=" + changeCommon('userProperty_key', baseAttr.userProperty) + " + /> + </span> + <div class="content slider-box"> + <input + v-model="baseAttr.userProperty[k].value" + @change=" + changeCommon('userProperty_value', baseAttr.userProperty) + " + /> + </div> + </div> + </li> + <li + class="flex-view" + style="justify-content: center; color: dodgerblue; text-align: center" + @click=" + () => { + baseAttr.userProperty.push({ + key: 'key' + baseAttr.userProperty.length, + value: 'value' + }); + } + " + > + <span>新增一项</span> + </li> + </ul> + </div> --> + </div> +</template> diff --git a/src/views/deviceSetting/components/deviceSelect.vue b/src/views/deviceSetting/components/deviceSelect.vue index a5042ce..8275308 100644 --- a/src/views/deviceSetting/components/deviceSelect.vue +++ b/src/views/deviceSetting/components/deviceSelect.vue @@ -4,12 +4,17 @@ <template> <div v-if="!mixinState.mSelectMode"> - <div class="content"> + <div class="px-[12px] deviceSelect_toolbar"> <div> - <span>本地模型</span> - <ul> + <h4 class="hf-1 py-[12px]">设备列表</h4> + <p class="pf-2"> + 可直接点击拖拽设备名称至图中目标位置,鼠标悬停可查看设备详情 + </p> + <ul class="mt-[8px] deviceSelect_list"> <li - v-for="(info, i) in locaWatchList" + class="flex items-center px-[16px] mb-[12px]" + :class="detailInfo?.id === info.id ? 'active' : ''" + v-for="(info, i) in props.deviceList" :key="`${i}-logo1-button`" :draggable="true" @click="addItem(info)" @@ -31,15 +36,19 @@ import useSelect from "@/hooks/select"; // import { cloneDeep } from "lodash-es"; import { v4 as uuid } from "uuid"; // import { useI18n } from "vue-i18n"; -import { useWatchModels } from "../hooks/useWatchModels"; import { useDeviceObject } from "../hooks/useDeviceObject"; // import watchOnlineSelected from "../../../assets/modelSetting/watchOnlineSelected.svg"; // const testSrc = // "https://img.cgmodel.com/image/2020/1010/big/1537169-1390622992.jpg"; +const props = defineProps({ + deviceList: { + type: Array as Record<string, any>[] + } +}); + const { fabric, mixinState, canvasEditor } = useSelect(); -const { locaWatchList } = useWatchModels(); const { initDeviceGroupObjects } = useDeviceObject(); // const { t } = useI18n(); const defaultPosition = { @@ -75,7 +84,7 @@ const state = reactive({ materialTypelist: [], // 分类列表 materialist: [] // 列表内容 }); - +const detailInfo = ref({}); // 获取素材分类 canvasEditor.getMaterialType("svg").then((list: materialTypeI[]) => { state.materialTypelist = [...list]; @@ -85,43 +94,31 @@ canvasEditor.getMaterialType("svg").then((list: materialTypeI[]) => { // 切换素材类型 // const handleChange = (e, item) => { // // 搜索框文字设置 -// const { label, value } = item[0]; -// state.placeholder = label; -// state.search = ""; -// filterTypeList(value); -// }; -// 模板搜索功能 -// const filterTypeList = (value: string) => { -// // 全部类型 -// if (!value) { -// state.materialist = cloneDeep(state.materialTypelist); -// } else { -// // 当前分类详情 -// const materialTypeInfoList = -// state.materialTypelist.filter(item => item.value === value) || []; -// state.materialist = materialTypeInfoList; -// } +// 获取素材分类 +canvasEditor.getMaterialType("svg").then((list: materialTypeI[]) => { + state.materialTypelist = [...list]; + state.materialist = list; +}); -// // 展示分类 -// if (state.search) { -// const list = cloneDeep(state.materialist); -// // 按照搜索内容展示 -// state.materialist = list.map(item => { -// if (item.list) { -// item.list = item.list.filter(info => info.label.includes(state.search)); -// } -// return item; -// }); -// } -// }; +function fetchDetail(record) { + detailInfo.value = record; + console.log(detailInfo.value, "fetchDetail"); +} -// const search = () => { -// const [typeValue] = state.materialType; -// filterTypeList(typeValue); -// }; +/** + * 校验是否允许添加设备 + * @param record 选中的素材 + */ +function isValidAdd(record) { + console.log("isValidAdd_record", record); + return false; +} const dragItem = (event, deviceItem) => { + if (isValidAdd(deviceItem)) { + return; + } console.log(event, deviceItem, "dragItem"); fabric.util.enlivenObjects( [ @@ -146,6 +143,7 @@ const dragItem = (event, deviceItem) => { // var canvas = new fabric.Canvas('canvas-id'); // canvas.add(group); canvasEditor.dragAddItem(event, item); + fetchDetail(deviceItem); // 更新Canvas以确保更改生效 // canvas.renderAll(); } @@ -154,20 +152,9 @@ const dragItem = (event, deviceItem) => { // 按照类型渲染 const addItem = deviceItem => { - // fabric.util.enlivenObjects(deviceItem.groupObject?.objects, enlivenedObjects => { - // const item = new fabric.Group(enlivenedObjects, { - // // ...options, - // ...defaultPosition, - // shadow: "", - // fontFamily: "arial", - // id: uuid(), - // name: "设备元素" - // }); - // canvasEditor.canvas.add(item); - // canvasEditor.canvas.setActiveObject(item); - // canvasEditor.canvas.requestRenderAll(); - // }); - + if (isValidAdd(deviceItem)) { + return; + } fabric.util.enlivenObjects( [ { @@ -191,6 +178,7 @@ const addItem = deviceItem => { canvasEditor.canvas.add(item); canvasEditor.canvas.setActiveObject(item); canvasEditor.canvas.requestRenderAll(); + fetchDetail(deviceItem); // 更新Canvas以确保更改生效 // canvas.renderAll(); } @@ -247,8 +235,8 @@ const addItem = deviceItem => { // } // ]); const DefaultSize = { - width: 1200, - height: 900 + width: 947, + height: 642 }; onMounted(() => { canvasEditor.setSize(DefaultSize.width, DefaultSize.height); diff --git a/src/views/deviceSetting/hooks/useWatchModels.ts b/src/views/deviceSetting/hooks/useDe.ts similarity index 100% rename from src/views/deviceSetting/hooks/useWatchModels.ts rename to src/views/deviceSetting/hooks/useDe.ts diff --git a/src/views/deviceSetting/hooks/useDeviceObject.ts b/src/views/deviceSetting/hooks/useDeviceObject.ts index 690f2d0..2ffe938 100644 --- a/src/views/deviceSetting/hooks/useDeviceObject.ts +++ b/src/views/deviceSetting/hooks/useDeviceObject.ts @@ -2,6 +2,9 @@ * @交互说明 * 1. 初始化选中目标的设备对象 【设备名称、使用图标】 */ +// https://t7.baidu.com/it/u=2757924858,1404466263&fm=193 +import video_type_1 from "@/assets/modelSetting/video_type_1.png"; + export const useDeviceObject = () => { const initDeviceGroupObjects: Record<string, any> = (record: { id: string; @@ -36,9 +39,9 @@ export const useDeviceObject = () => { version: "5.3.0", originX: "left", originY: "top", - left: 20.9866, - top: 16.4716, - width: 131, + left: 87.4695, + top: 85.8002, + width: 113, height: 66, fill: "rgb(0,0,0)", stroke: null, @@ -63,15 +66,16 @@ export const useDeviceObject = () => { globalCompositeOperation: "source-over", skewX: 0, skewY: 0, + id: "520579bf-b8b3-451b-b3aa-5b8a9d6cd1a8", objects: [ { - type: "group", + type: "image", version: "5.3.0", originX: "left", originY: "top", - left: -65.5, + left: -56.5, top: -33, - width: 131, + width: 113, height: 66, fill: "rgb(0,0,0)", stroke: null, @@ -88,7 +92,7 @@ export const useDeviceObject = () => { flipX: false, flipY: false, opacity: 1, - shadow: "", + shadow: null, visible: true, backgroundColor: "", fillRule: "nonzero", @@ -96,438 +100,65 @@ export const useDeviceObject = () => { globalCompositeOperation: "source-over", skewX: 0, skewY: 0, - selectable: true, - hasControls: true, - objects: [ - { - type: "path", - version: "5.3.0", - originX: "left", - originY: "top", - left: -60, - top: -31.5, - width: 119, - height: 54, - fill: "white", - stroke: null, - strokeWidth: 1, - strokeDashArray: null, - strokeLineCap: "butt", - strokeDashOffset: 0, - strokeLineJoin: "miter", - strokeUniform: false, - strokeMiterLimit: 4, - scaleX: 1, - scaleY: 1, - angle: 0, - flipX: false, - flipY: false, - opacity: 1, - shadow: null, - visible: true, - backgroundColor: "", - fillRule: "evenodd", - paintFirst: "fill", - globalCompositeOperation: "source-over", - skewX: 0, - skewY: 0, - selectable: true, - hasControls: true, - path: [ - ["M", 10, 2], - ["C", 7.79086, 2, 6, 3.79086, 6, 6], - ["L", 6, 44], - ["C", 6, 46.2091, 7.79086, 48, 10, 48], - ["L", 58.8, 48], - ["L", 66, 56], - ["L", 73.2, 48], - ["L", 121, 48], - ["C", 123.209, 48, 125, 46.2091, 125, 44], - ["L", 125, 6], - ["C", 125, 3.79086, 123.209, 2, 121, 2], - ["L", 10, 2], - ["Z"] - ] - }, - { - type: "path", - version: "5.3.0", - originX: "left", - originY: "top", - left: -61, - top: -32.5, - width: 121, - height: 56.4948, - fill: "rgba(21,77,221,0.2)", - stroke: null, - strokeWidth: 1, - strokeDashArray: null, - strokeLineCap: "butt", - strokeDashOffset: 0, - strokeLineJoin: "miter", - strokeUniform: false, - strokeMiterLimit: 4, - scaleX: 1, - scaleY: 1, - angle: 0, - flipX: false, - flipY: false, - opacity: 1, - shadow: null, - visible: true, - backgroundColor: "", - fillRule: "nonzero", - paintFirst: "fill", - globalCompositeOperation: "source-over", - skewX: 0, - skewY: 0, - selectable: true, - hasControls: true, - path: [ - ["M", 58.8, 48], - ["L", 59.5433, 47.331], - ["L", 59.2454, 47], - ["L", 58.8, 47], - ["L", 58.8, 48], - ["Z"], - ["M", 66, 56], - ["L", 65.2567, 56.669], - ["L", 66, 57.4948], - ["L", 66.7433, 56.669], - ["L", 66, 56], - ["Z"], - ["M", 73.2, 48], - ["L", 73.2, 47], - ["L", 72.7546, 47], - ["L", 72.4567, 47.331], - ["L", 73.2, 48], - ["Z"], - ["M", 7, 6], - ["C", 7, 4.34315, 8.34315, 3, 10, 3], - ["L", 10, 1], - ["C", 7.23858, 1, 5, 3.23857, 5, 6], - ["L", 7, 6], - ["Z"], - ["M", 7, 44], - ["L", 7, 6], - ["L", 5, 6], - ["L", 5, 44], - ["L", 7, 44], - ["Z"], - ["M", 10, 47], - ["C", 8.34315, 47, 7, 45.6569, 7, 44], - ["L", 5, 44], - ["C", 5, 46.7614, 7.23858, 49, 10, 49], - ["L", 10, 47], - ["Z"], - ["M", 58.8, 47], - ["L", 10, 47], - ["L", 10, 49], - ["L", 58.8, 49], - ["L", 58.8, 47], - ["Z"], - ["M", 58.0567, 48.669], - ["L", 65.2567, 56.669], - ["L", 66.7433, 55.331], - ["L", 59.5433, 47.331], - ["L", 58.0567, 48.669], - ["Z"], - ["M", 66.7433, 56.669], - ["L", 73.9433, 48.669], - ["L", 72.4567, 47.331], - ["L", 65.2567, 55.331], - ["L", 66.7433, 56.669], - ["Z"], - ["M", 121, 47], - ["L", 73.2, 47], - ["L", 73.2, 49], - ["L", 121, 49], - ["L", 121, 47], - ["Z"], - ["M", 124, 44], - ["C", 124, 45.6569, 122.657, 47, 121, 47], - ["L", 121, 49], - ["C", 123.761, 49, 126, 46.7614, 126, 44], - ["L", 124, 44], - ["Z"], - ["M", 124, 6], - ["L", 124, 44], - ["L", 126, 44], - ["L", 126, 6], - ["L", 124, 6], - ["Z"], - ["M", 121, 3], - ["C", 122.657, 3, 124, 4.34315, 124, 6], - ["L", 126, 6], - ["C", 126, 3.23858, 123.761, 1, 121, 1], - ["L", 121, 3], - ["Z"], - ["M", 10, 3], - ["L", 121, 3], - ["L", 121, 1], - ["L", 10, 1], - ["L", 10, 3], - ["Z"] - ] - }, - { - type: "rect", - version: "5.3.0", - originX: "left", - originY: "top", - left: -52, - top: -24.5, - width: 32, - height: 32, - fill: "#52C41A", - stroke: null, - strokeWidth: 1, - strokeDashArray: null, - strokeLineCap: "butt", - strokeDashOffset: 0, - strokeLineJoin: "miter", - strokeUniform: false, - strokeMiterLimit: 4, - scaleX: 1, - scaleY: 1, - angle: 0, - flipX: false, - flipY: false, - opacity: 1, - shadow: null, - visible: true, - backgroundColor: "", - fillRule: "nonzero", - paintFirst: "fill", - globalCompositeOperation: "source-over", - skewX: 0, - skewY: 0, - rx: 2, - ry: 2, - selectable: true, - hasControls: true - }, - { - type: "path", - version: "5.3.0", - originX: "left", - originY: "top", - left: -45.9945, - top: -17.6, - width: 19.8963, - height: 0, - fill: "", - stroke: "white", - strokeWidth: 1.2, - strokeDashArray: null, - strokeLineCap: "round", - strokeDashOffset: 0, - strokeLineJoin: "round", - strokeUniform: false, - strokeMiterLimit: 4, - scaleX: 1, - scaleY: 1, - angle: 0, - flipX: false, - flipY: false, - opacity: 1, - shadow: null, - visible: true, - backgroundColor: "", - fillRule: "nonzero", - paintFirst: "fill", - globalCompositeOperation: "source-over", - skewX: 0, - skewY: 0, - selectable: true, - hasControls: true, - path: [ - ["M", 40.0018, 16], - ["L", 29.5301, 16], - ["L", 20.1055, 16] - ] - }, - { - type: "path", - version: "5.3.0", - originX: "left", - originY: "top", - left: -36.5727, - top: -17.6, - width: 0, - height: 8.8419, - fill: "", - stroke: "white", - strokeWidth: 1.2, - strokeDashArray: null, - strokeLineCap: "round", - strokeDashOffset: 0, - strokeLineJoin: "round", - strokeUniform: false, - strokeMiterLimit: 4, - scaleX: 1, - scaleY: 1, - angle: 0, - flipX: false, - flipY: false, - opacity: 1, - shadow: null, - visible: true, - backgroundColor: "", - fillRule: "nonzero", - paintFirst: "fill", - globalCompositeOperation: "source-over", - skewX: 0, - skewY: 0, - selectable: true, - hasControls: true, - path: [ - ["M", 29.5273, 24.8419], - ["L", 29.5273, 16] - ] - }, - { - type: "path", - version: "5.3.0", - originX: "left", - originY: "top", - left: -46.1, - top: -10.5375, - width: 18.5869, - height: 10.9372, - fill: "white", - stroke: "white", - strokeWidth: 1.2, - strokeDashArray: null, - strokeLineCap: "round", - strokeDashOffset: 0, - strokeLineJoin: "round", - strokeUniform: false, - strokeMiterLimit: 4, - scaleX: 1, - scaleY: 1, - angle: 0, - flipX: false, - flipY: false, - opacity: 1, - shadow: null, - visible: true, - backgroundColor: "", - fillRule: "nonzero", - paintFirst: "fill", - globalCompositeOperation: "source-over", - skewX: 0, - skewY: 0, - selectable: true, - hasControls: true, - path: [ - ["M", 21.8972, 23.0625], - ["L", 38.5869, 27.5048], - ["L", 37.6746, 28.8773], - ["L", 35.579, 32.6272], - ["L", 34.6667, 33.9997], - ["L", 20, 30.0959], - ["L", 21.8972, 23.0625], - ["Z"] - ] - }, - { - type: "path", - version: "5.3.0", - originX: "left", - originY: "top", - left: -30.5219, - top: -4.7211, - width: 4.1186, - height: 4.5576, - fill: "", - stroke: "white", - strokeWidth: 1.2, - strokeDashArray: null, - strokeLineCap: "round", - strokeDashOffset: 0, - strokeLineJoin: "round", - strokeUniform: false, - strokeMiterLimit: 4, - scaleX: 1, - scaleY: 1, - angle: 0, - flipX: false, - flipY: false, - opacity: 1, - shadow: null, - visible: true, - backgroundColor: "", - fillRule: "nonzero", - paintFirst: "fill", - globalCompositeOperation: "source-over", - skewX: 0, - skewY: 0, - selectable: true, - hasControls: true, - path: [ - ["M", 37.6737, 28.8789], - ["L", 39.6967, 29.4174], - ["L", 38.6126, 33.4365], - ["L", 35.5781, 32.6288] - ] - }, - { - type: "path", - version: "5.3.0", - originX: "left", - originY: "top", - left: -43.3008, - top: -7.6387, - width: 4.2123, - height: 4.181, - fill: "", - stroke: "#52C41A", - strokeWidth: 0.5, - strokeDashArray: null, - strokeLineCap: "butt", - strokeDashOffset: 0, - strokeLineJoin: "miter", - strokeUniform: false, - strokeMiterLimit: 4, - scaleX: 1, - scaleY: 1, - angle: 0, - flipX: false, - flipY: false, - opacity: 1, - shadow: null, - visible: true, - backgroundColor: "", - fillRule: "nonzero", - paintFirst: "fill", - globalCompositeOperation: "source-over", - skewX: 0, - skewY: 0, - selectable: true, - hasControls: true, - path: [ - ["M", 26.6615, 27.7018], - ["C", 26.6615, 28.8548, 25.7201, 29.7923, 24.5554, 29.7923], - ["C", 23.3906, 29.7923, 22.4492, 28.8548, 22.4492, 27.7018], - ["C", 22.4492, 26.5488, 23.3906, 25.6113, 24.5554, 25.6113], - ["C", 25.7201, 25.6113, 26.6615, 26.5488, 26.6615, 27.7018], - ["Z"] - ] - } - ] + cropX: 0, + cropY: 0, + selectable: false, + hasControls: false, + src: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTEzIiBoZWlnaHQ9IjY2IiB2aWV3Qm94PSIwIDAgMTEzIDY2IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8ZyBmaWx0ZXI9InVybCgjZmlsdGVyMF9kXzIyMDNfMTAzMTgpIj4KPG1hc2sgaWQ9InBhdGgtMS1pbnNpZGUtMV8yMjAzXzEwMzE4IiBmaWxsPSJ3aGl0ZSI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTAgMkM3Ljc5MDg2IDIgNiAzLjc5MDg2IDYgNlY0NEM2IDQ2LjIwOTEgNy43OTA4NiA0OCAxMCA0OEg0OS44TDU3IDU2TDY0LjIgNDhIMTAzQzEwNS4yMDkgNDggMTA3IDQ2LjIwOTEgMTA3IDQ0VjZDMTA3IDMuNzkwODYgMTA1LjIwOSAyIDEwMyAySDEwWiIvPgo8L21hc2s+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTAgMkM3Ljc5MDg2IDIgNiAzLjc5MDg2IDYgNlY0NEM2IDQ2LjIwOTEgNy43OTA4NiA0OCAxMCA0OEg0OS44TDU3IDU2TDY0LjIgNDhIMTAzQzEwNS4yMDkgNDggMTA3IDQ2LjIwOTEgMTA3IDQ0VjZDMTA3IDMuNzkwODYgMTA1LjIwOSAyIDEwMyAySDEwWiIgZmlsbD0id2hpdGUiIGZpbGwtb3BhY2l0eT0iMC44IiBzaGFwZS1yZW5kZXJpbmc9ImNyaXNwRWRnZXMiLz4KPHBhdGggZD0iTTQ5LjggNDhMNTAuNTQzMyA0Ny4zMzFMNTAuMjQ1NCA0N0g0OS44VjQ4Wk01NyA1Nkw1Ni4yNTY3IDU2LjY2OUw1NyA1Ny40OTQ4TDU3Ljc0MzMgNTYuNjY5TDU3IDU2Wk02NC4yIDQ4VjQ3SDYzLjc1NDZMNjMuNDU2NyA0Ny4zMzFMNjQuMiA0OFpNNyA2QzcgNC4zNDMxNSA4LjM0MzE1IDMgMTAgM1YxQzcuMjM4NTggMSA1IDMuMjM4NTcgNSA2SDdaTTcgNDRWNkg1VjQ0SDdaTTEwIDQ3QzguMzQzMTUgNDcgNyA0NS42NTY5IDcgNDRINUM1IDQ2Ljc2MTQgNy4yMzg1NyA0OSAxMCA0OVY0N1pNNDkuOCA0N0gxMFY0OUg0OS44VjQ3Wk00OS4wNTY3IDQ4LjY2OUw1Ni4yNTY3IDU2LjY2OUw1Ny43NDMzIDU1LjMzMUw1MC41NDMzIDQ3LjMzMUw0OS4wNTY3IDQ4LjY2OVpNNTcuNzQzMyA1Ni42NjlMNjQuOTQzMyA0OC42NjlMNjMuNDU2NyA0Ny4zMzFMNTYuMjU2NyA1NS4zMzFMNTcuNzQzMyA1Ni42NjlaTTEwMyA0N0g2NC4yVjQ5SDEwM1Y0N1pNMTA2IDQ0QzEwNiA0NS42NTY5IDEwNC42NTcgNDcgMTAzIDQ3VjQ5QzEwNS43NjEgNDkgMTA4IDQ2Ljc2MTQgMTA4IDQ0SDEwNlpNMTA2IDZWNDRIMTA4VjZIMTA2Wk0xMDMgM0MxMDQuNjU3IDMgMTA2IDQuMzQzMTUgMTA2IDZIMTA4QzEwOCAzLjIzODU4IDEwNS43NjEgMSAxMDMgMVYzWk0xMCAzSDEwM1YxSDEwVjNaIiBmaWxsPSJ3aGl0ZSIgbWFzaz0idXJsKCNwYXRoLTEtaW5zaWRlLTFfMjIwM18xMDMxOCkiLz4KPC9nPgo8ZGVmcz4KPGZpbHRlciBpZD0iZmlsdGVyMF9kXzIyMDNfMTAzMTgiIHg9IjAiIHk9IjAiIHdpZHRoPSIxMTMiIGhlaWdodD0iNjYiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz4KPGZlQ29sb3JNYXRyaXggaW49IlNvdXJjZUFscGhhIiB0eXBlPSJtYXRyaXgiIHZhbHVlcz0iMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMTI3IDAiIHJlc3VsdD0iaGFyZEFscGhhIi8+CjxmZU9mZnNldCBkeT0iNCIvPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIzIi8+CjxmZUNvbXBvc2l0ZSBpbjI9ImhhcmRBbHBoYSIgb3BlcmF0b3I9Im91dCIvPgo8ZmVDb2xvck1hdHJpeCB0eXBlPSJtYXRyaXgiIHZhbHVlcz0iMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMC4xIDAiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJlZmZlY3QxX2Ryb3BTaGFkb3dfMjIwM18xMDMxOCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9ImVmZmVjdDFfZHJvcFNoYWRvd18yMjAzXzEwMzE4IiByZXN1bHQ9InNoYXBlIi8+CjwvZmlsdGVyPgo8L2RlZnM+Cjwvc3ZnPgo=", + crossOrigin: null, + filters: [] }, { - type: "textbox", + type: "image", version: "5.3.0", originX: "left", originY: "top", - left: -15.709, - top: -15.0177, - width: 67.6873, - height: 13.56, + left: -40.6281, + top: -22.9893, + width: 48, + height: 48, fill: "rgb(0,0,0)", stroke: null, + strokeWidth: 0, + strokeDashArray: null, + strokeLineCap: "butt", + strokeDashOffset: 0, + strokeLineJoin: "miter", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 0.6174, + scaleY: 0.6174, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + cropX: 0, + cropY: 0, + selectable: false, + hasControls: false, + src: video_type_1, + crossOrigin: null, + filters: [] + }, + { + type: "textbox", + version: "5.3.0", + originX: "left", + originY: "top", + left: -7.3377, + top: -15.4904, + width: 320, + height: 90.4, + fill: "#333333", + stroke: null, strokeWidth: 1, strokeDashArray: null, strokeLineCap: "butt", @@ -535,8 +166,8 @@ export const useDeviceObject = () => { strokeLineJoin: "miter", strokeUniform: false, strokeMiterLimit: 4, - scaleX: 1, - scaleY: 1, + scaleX: 0.1681, + scaleY: 0.1681, angle: 0, flipX: false, flipY: false, @@ -551,8 +182,8 @@ export const useDeviceObject = () => { skewY: 0, fontFamily: "arial", fontWeight: "normal", - fontSize: 12, - text: record?.name || "设备", + fontSize: 80, + text: record?.name, underline: false, overline: false, linethrough: false, @@ -567,10 +198,8 @@ export const useDeviceObject = () => { pathStartOffset: 0, pathSide: "left", pathAlign: "baseline", - minWidth: 20, - splitByGrapheme: true, - selectable: true, - hasControls: true + selectable: false, + hasControls: false } ] }; diff --git a/src/views/deviceSetting/hooks/useDeviceObject1.ts b/src/views/deviceSetting/hooks/useDeviceObject1.ts new file mode 100644 index 0000000..690f2d0 --- /dev/null +++ b/src/views/deviceSetting/hooks/useDeviceObject1.ts @@ -0,0 +1,581 @@ +/** + * @交互说明 + * 1. 初始化选中目标的设备对象 【设备名称、使用图标】 + */ +export const useDeviceObject = () => { + const initDeviceGroupObjects: Record<string, any> = (record: { + id: string; + value: string; + }) => { + console.log(record, "initDeviceGroupObjects"); + // const { value } = record; + // let watchIconObject = watchIcon2; + // switch (value) { + // case "watchError": + // watchIconObject = watchIcon1; + // break; + // case "watchOnline": + // watchIconObject = watchIcon2; + // break; + // case "watchOutline": + // watchIconObject = watchIcon3; + // break; + // case "watchWarn": + // default: + // watchIconObject = watchIcon4; + // break; + // } + return { + selectable: true, + hasControls: true, + lockUniScaling: true, // 当设置为true,Object将无法被锁定比例进行缩放。默认值为false。 + lockScalingX: true, // 当设置为true,Object水平方向将无法被缩放。默认值为false。 + lockScalingY: true, // 当设置为true,Object垂直方向将无法被缩放。默认值为false。 + lockRotation: true, // 当设置为true,Object的旋转将被锁定。默认值为false。 + type: "group", + version: "5.3.0", + originX: "left", + originY: "top", + left: 20.9866, + top: 16.4716, + width: 131, + height: 66, + fill: "rgb(0,0,0)", + stroke: null, + strokeWidth: 0, + strokeDashArray: null, + strokeLineCap: "butt", + strokeDashOffset: 0, + strokeLineJoin: "miter", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + objects: [ + { + type: "group", + version: "5.3.0", + originX: "left", + originY: "top", + left: -65.5, + top: -33, + width: 131, + height: 66, + fill: "rgb(0,0,0)", + stroke: null, + strokeWidth: 0, + strokeDashArray: null, + strokeLineCap: "butt", + strokeDashOffset: 0, + strokeLineJoin: "miter", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: "", + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + selectable: true, + hasControls: true, + objects: [ + { + type: "path", + version: "5.3.0", + originX: "left", + originY: "top", + left: -60, + top: -31.5, + width: 119, + height: 54, + fill: "white", + stroke: null, + strokeWidth: 1, + strokeDashArray: null, + strokeLineCap: "butt", + strokeDashOffset: 0, + strokeLineJoin: "miter", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + backgroundColor: "", + fillRule: "evenodd", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + selectable: true, + hasControls: true, + path: [ + ["M", 10, 2], + ["C", 7.79086, 2, 6, 3.79086, 6, 6], + ["L", 6, 44], + ["C", 6, 46.2091, 7.79086, 48, 10, 48], + ["L", 58.8, 48], + ["L", 66, 56], + ["L", 73.2, 48], + ["L", 121, 48], + ["C", 123.209, 48, 125, 46.2091, 125, 44], + ["L", 125, 6], + ["C", 125, 3.79086, 123.209, 2, 121, 2], + ["L", 10, 2], + ["Z"] + ] + }, + { + type: "path", + version: "5.3.0", + originX: "left", + originY: "top", + left: -61, + top: -32.5, + width: 121, + height: 56.4948, + fill: "rgba(21,77,221,0.2)", + stroke: null, + strokeWidth: 1, + strokeDashArray: null, + strokeLineCap: "butt", + strokeDashOffset: 0, + strokeLineJoin: "miter", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + selectable: true, + hasControls: true, + path: [ + ["M", 58.8, 48], + ["L", 59.5433, 47.331], + ["L", 59.2454, 47], + ["L", 58.8, 47], + ["L", 58.8, 48], + ["Z"], + ["M", 66, 56], + ["L", 65.2567, 56.669], + ["L", 66, 57.4948], + ["L", 66.7433, 56.669], + ["L", 66, 56], + ["Z"], + ["M", 73.2, 48], + ["L", 73.2, 47], + ["L", 72.7546, 47], + ["L", 72.4567, 47.331], + ["L", 73.2, 48], + ["Z"], + ["M", 7, 6], + ["C", 7, 4.34315, 8.34315, 3, 10, 3], + ["L", 10, 1], + ["C", 7.23858, 1, 5, 3.23857, 5, 6], + ["L", 7, 6], + ["Z"], + ["M", 7, 44], + ["L", 7, 6], + ["L", 5, 6], + ["L", 5, 44], + ["L", 7, 44], + ["Z"], + ["M", 10, 47], + ["C", 8.34315, 47, 7, 45.6569, 7, 44], + ["L", 5, 44], + ["C", 5, 46.7614, 7.23858, 49, 10, 49], + ["L", 10, 47], + ["Z"], + ["M", 58.8, 47], + ["L", 10, 47], + ["L", 10, 49], + ["L", 58.8, 49], + ["L", 58.8, 47], + ["Z"], + ["M", 58.0567, 48.669], + ["L", 65.2567, 56.669], + ["L", 66.7433, 55.331], + ["L", 59.5433, 47.331], + ["L", 58.0567, 48.669], + ["Z"], + ["M", 66.7433, 56.669], + ["L", 73.9433, 48.669], + ["L", 72.4567, 47.331], + ["L", 65.2567, 55.331], + ["L", 66.7433, 56.669], + ["Z"], + ["M", 121, 47], + ["L", 73.2, 47], + ["L", 73.2, 49], + ["L", 121, 49], + ["L", 121, 47], + ["Z"], + ["M", 124, 44], + ["C", 124, 45.6569, 122.657, 47, 121, 47], + ["L", 121, 49], + ["C", 123.761, 49, 126, 46.7614, 126, 44], + ["L", 124, 44], + ["Z"], + ["M", 124, 6], + ["L", 124, 44], + ["L", 126, 44], + ["L", 126, 6], + ["L", 124, 6], + ["Z"], + ["M", 121, 3], + ["C", 122.657, 3, 124, 4.34315, 124, 6], + ["L", 126, 6], + ["C", 126, 3.23858, 123.761, 1, 121, 1], + ["L", 121, 3], + ["Z"], + ["M", 10, 3], + ["L", 121, 3], + ["L", 121, 1], + ["L", 10, 1], + ["L", 10, 3], + ["Z"] + ] + }, + { + type: "rect", + version: "5.3.0", + originX: "left", + originY: "top", + left: -52, + top: -24.5, + width: 32, + height: 32, + fill: "#52C41A", + stroke: null, + strokeWidth: 1, + strokeDashArray: null, + strokeLineCap: "butt", + strokeDashOffset: 0, + strokeLineJoin: "miter", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + rx: 2, + ry: 2, + selectable: true, + hasControls: true + }, + { + type: "path", + version: "5.3.0", + originX: "left", + originY: "top", + left: -45.9945, + top: -17.6, + width: 19.8963, + height: 0, + fill: "", + stroke: "white", + strokeWidth: 1.2, + strokeDashArray: null, + strokeLineCap: "round", + strokeDashOffset: 0, + strokeLineJoin: "round", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + selectable: true, + hasControls: true, + path: [ + ["M", 40.0018, 16], + ["L", 29.5301, 16], + ["L", 20.1055, 16] + ] + }, + { + type: "path", + version: "5.3.0", + originX: "left", + originY: "top", + left: -36.5727, + top: -17.6, + width: 0, + height: 8.8419, + fill: "", + stroke: "white", + strokeWidth: 1.2, + strokeDashArray: null, + strokeLineCap: "round", + strokeDashOffset: 0, + strokeLineJoin: "round", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + selectable: true, + hasControls: true, + path: [ + ["M", 29.5273, 24.8419], + ["L", 29.5273, 16] + ] + }, + { + type: "path", + version: "5.3.0", + originX: "left", + originY: "top", + left: -46.1, + top: -10.5375, + width: 18.5869, + height: 10.9372, + fill: "white", + stroke: "white", + strokeWidth: 1.2, + strokeDashArray: null, + strokeLineCap: "round", + strokeDashOffset: 0, + strokeLineJoin: "round", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + selectable: true, + hasControls: true, + path: [ + ["M", 21.8972, 23.0625], + ["L", 38.5869, 27.5048], + ["L", 37.6746, 28.8773], + ["L", 35.579, 32.6272], + ["L", 34.6667, 33.9997], + ["L", 20, 30.0959], + ["L", 21.8972, 23.0625], + ["Z"] + ] + }, + { + type: "path", + version: "5.3.0", + originX: "left", + originY: "top", + left: -30.5219, + top: -4.7211, + width: 4.1186, + height: 4.5576, + fill: "", + stroke: "white", + strokeWidth: 1.2, + strokeDashArray: null, + strokeLineCap: "round", + strokeDashOffset: 0, + strokeLineJoin: "round", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + selectable: true, + hasControls: true, + path: [ + ["M", 37.6737, 28.8789], + ["L", 39.6967, 29.4174], + ["L", 38.6126, 33.4365], + ["L", 35.5781, 32.6288] + ] + }, + { + type: "path", + version: "5.3.0", + originX: "left", + originY: "top", + left: -43.3008, + top: -7.6387, + width: 4.2123, + height: 4.181, + fill: "", + stroke: "#52C41A", + strokeWidth: 0.5, + strokeDashArray: null, + strokeLineCap: "butt", + strokeDashOffset: 0, + strokeLineJoin: "miter", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + selectable: true, + hasControls: true, + path: [ + ["M", 26.6615, 27.7018], + ["C", 26.6615, 28.8548, 25.7201, 29.7923, 24.5554, 29.7923], + ["C", 23.3906, 29.7923, 22.4492, 28.8548, 22.4492, 27.7018], + ["C", 22.4492, 26.5488, 23.3906, 25.6113, 24.5554, 25.6113], + ["C", 25.7201, 25.6113, 26.6615, 26.5488, 26.6615, 27.7018], + ["Z"] + ] + } + ] + }, + { + type: "textbox", + version: "5.3.0", + originX: "left", + originY: "top", + left: -15.709, + top: -15.0177, + width: 67.6873, + height: 13.56, + fill: "rgb(0,0,0)", + stroke: null, + strokeWidth: 1, + strokeDashArray: null, + strokeLineCap: "butt", + strokeDashOffset: 0, + strokeLineJoin: "miter", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: "", + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + fontFamily: "arial", + fontWeight: "normal", + fontSize: 12, + text: record?.name || "设备", + underline: false, + overline: false, + linethrough: false, + textAlign: "left", + fontStyle: "normal", + lineHeight: 1.16, + textBackgroundColor: "", + charSpacing: 0, + styles: [], + direction: "ltr", + path: null, + pathStartOffset: 0, + pathSide: "left", + pathAlign: "baseline", + minWidth: 20, + splitByGrapheme: true, + selectable: true, + hasControls: true + } + ] + }; + }; + return { + initDeviceGroupObjects + }; +}; diff --git a/src/views/deviceSetting/hooks/usePointObject.ts b/src/views/deviceSetting/hooks/usePointObject.ts new file mode 100644 index 0000000..af52638 --- /dev/null +++ b/src/views/deviceSetting/hooks/usePointObject.ts @@ -0,0 +1,93 @@ +export const usePointObject = () => { + function getPointObject(record) { + const { imgUrl } = record; + // TODO: 获取点位对象 + return JSON.stringify({ + version: "5.3.0", + objects: [ + { + type: "rect", + version: "5.3.0", + originX: "left", + originY: "top", + left: 0, + top: 0, + width: 947, + height: 610, + fill: "rgba(255,35,255,1)", + stroke: null, + strokeWidth: 0, + strokeDashArray: null, + strokeLineCap: "butt", + strokeDashOffset: 0, + strokeLineJoin: "miter", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + rx: 0, + ry: 0, + id: "workspace", + selectable: false, + hasControls: false + }, + { + type: "image", + version: "5.3.0", + originX: "left", + originY: "top", + width: 947, + height: 610, + fill: "rgb(0,0,0)", + stroke: null, + strokeWidth: 0, + strokeDashArray: null, + strokeLineCap: "butt", + strokeDashOffset: 0, + strokeLineJoin: "miter", + strokeUniform: false, + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + skewX: 0, + skewY: 0, + cropX: 0, + cropY: 0, + id: "a3ab29c6-7008-49fe-abf3-edc9a47cd460", + selectable: false, + hasControls: false, + evented: false, + crossOrigin: null, + src: imgUrl, + filters: [] + } + ] + }); + } + + return { + getPointObject + }; +}; diff --git a/src/views/deviceSetting/index.scss b/src/views/deviceSetting/index.scss index 4f112b4..fb2499e 100644 --- a/src/views/deviceSetting/index.scss +++ b/src/views/deviceSetting/index.scss @@ -11,11 +11,49 @@ font-size: 20px; color: #333333; border-bottom: 1px solid rgba(21, 77, 221, 0.2); + h3 { + box-sizing: border-box; + padding: 20px 0; + height: 62px; + font-weight: bold; + font-size: 16px; + color: #333333; + border-bottom: 1px solid rgba(21, 77, 221, 0.2); + } } .main_content { - /* background: red; */ height: calc(100vh - 160px); + margin: 16px 16px 0; + .el-tabs { + .el-tabs__header { + background: rgba(21, 77, 221, 0.1); + border-radius: 4px; + margin: 0 0 16px; + } + .el-tabs__nav-wrap { + .el-tabs__item { + padding-left: 16px; + padding-right: 16px; + margin-right: 16px; + height: 46px; + line-height: 22px; + color: #666666; + &.is-active { + font-weight: bold; + color: var(--el-color-primary) !important; + } + } + &::after { + content: ""; + position: absolute; + left: 0; + bottom: 0; + width: 100%; + height: 0px !important; + } + } + } .device_add_wrap { width: 57.64vw; margin: 0 auto; @@ -25,15 +63,23 @@ background-color: red; } } + .point_detail_wrap { + .deviceOfPoint_wrap { + background-color: red; + height: calc(100vh - 290px); + } + .footer_btns { + padding: 16px 0; + } + } } /* TODO 待使用 */ .right-bar { - width: 304px; + margin-left: 16px; + width: 241px; height: 100%; - padding: 10px; overflow-y: auto; - background: #fff; } #workspace { flex: 1; @@ -41,13 +87,16 @@ position: relative; overflow: hidden; } - - .content { - flex: 1; - width: 220px; - padding: 10px; - padding-top: 0; - height: 100%; - overflow-y: auto; +} +/* 选择设备栏位 */ +.deviceSelect_toolbar { + .deviceSelect_list { + li { + border-radius: 2px; + height: 40px; + &.active { + background: rgba(21, 77, 221, 0.1); + } + } } } diff --git a/src/views/deviceSetting/index.vue b/src/views/deviceSetting/index.vue index 45cf941..4b77576 100644 --- a/src/views/deviceSetting/index.vue +++ b/src/views/deviceSetting/index.vue @@ -1,68 +1,23 @@ -<template> - <div class="main_booy_container deviceSetting_wrap"> - <header class="flex items-center justify-between" v-if="state.showFabric"> - <h3 class="computePowerAllocation_header">设备布点</h3> - <div> - <el-button type="primary" @click="addLocal" v-if="localList.length" - >新建位置</el-button - > - </div> - <!-- 预览 --> - <!-- <previewCurrent /> --> - <!-- <save></save> --> - <!-- <waterMark /> --> - </header> - <div class="main_content"> - <div class="device_add_wrap" v-show="!localList.length"> - <div class="bg_preview"> - <!-- 图 --> - </div> - <p class="pt-[16px] pb-[24px] pf-1 leading-[16px]"> - 本页面为数据可视化大屏中设备点位界面的配置页,通过上传设备所处区域的实拍图或平面图后,根据设备的实际位置,简单的使用拖拽等操作将设备列表中的设备与位置进行匹配,使之能够在数据可视化大屏中更加精细化而直观的了解设备的具体位置与状态。 - </p> - <div class="flex justify-center"> - <el-button type="primary" @click="addLocal">新建位置</el-button> - </div> - </div> - <div - class="flex w-full h-full device_select_wrap" - v-show="localList.length" - > - <!-- <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick"> - <el-tab-pane label="User" name="first"></el-tab-pane> - </el-tabs> --> - <!-- 左侧画布区域 --> - <div id="workspace" class="h-full"> - <div class="canvas-box"> - <!-- <div class="inside-shadow"></div> --> - <canvas - id="canvas" - :class="state.ruler ? 'design-stage-grid' : ''" - /> - <!-- <dragMode v-if="state.showFabric"></dragMode> - <zoom></zoom> --> - <!-- <mouseMenu></mouseMenu> --> - </div> - </div> - <!-- 右侧属性区域--> - <div class="right-bar" v-if="state.showFabric"> - <DeviceSelect /> - <DeviceAttr /> - </div> - </div> - </div> - <DeviceSettingAdd ref="deviceSettingAddRef" /> - </div> -</template> - +<!-- + * @Author: donghao donghao@supervision.ltd + * @Date: 2024-08-02 10:52:32 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2024-08-13 14:37:07 + * @FilePath: \General-AI-Platform-Web-Client\src\views\deviceSetting\index.vue + * @Description: 设备点位管理设置 + @ 交互说明 + 1. 设备点位新增、编辑、删除 + 2. 设备点位&列表展示、切换 + 3. 设备点位拖拽点击关联、取消关联 + 4. 设备关联属性设置 + 5. 效果预览 +--> <script name="Home" setup> // 设备设置 import DeviceAttr from "./components/deviceAttr.vue"; import DeviceSettingAdd from "./components/add.vue"; import DeviceSelect from "./components/deviceSelect.vue"; - -// 测试数据 -import jsonFile1 from "./testData/bg01.json"; +import { usePointObject } from "./hooks/usePointObject"; // TODO 完善预览 // 功能组件 import { CanvasEventEmitter } from "@/utils/event/notifier"; @@ -90,11 +45,11 @@ import Editor, { MaterialPlugin } from "@/core"; -// 创建编辑器 +/** + * @fabric编辑器 + */ const canvasEditor = new Editor(); - const event = new CanvasEventEmitter(); - const state = reactive({ menuActive: 2, showFabric: false, @@ -104,24 +59,34 @@ const state = reactive({ ruler: false }); -// 设备&点位 -const localList = ref([]); +/** + * @设备点位 + */ +const { getPointObject } = usePointObject(); +const pointList = ref([]); const deviceSettingAddRef = ref(""); +const activePointId = ref(""); +const activePoint = ref({ + name: "" +}); +const deviceList = ref([]); // 插入文件 const initFile = () => { - console.log("canvasEditor"); - canvasEditor.insertSvgFile(jsonFile1); + // console.log("canvasEditor"); + canvasEditor.insertSvgFile(getPointObject(toRaw(activePoint.value))); }; - +// 初始化fabric&编辑器 const initFabric = () => { - // 初始化fabric const canvas = new fabric.Canvas("canvas", { fireRightClick: true, // 启用右键,button的数字为3 stopContextMenu: true, // 禁止默认右键菜单 controlsAboveOverlay: true // 超出clipPath后仍然展示控制条 }); - canvas.loadFromJSON(jsonFile1, canvas.renderAll.bind(canvas)); + canvas.loadFromJSON( + getPointObject(toRaw(activePoint.value)), + canvas.renderAll.bind(canvas) + ); // 初始化编辑器 canvasEditor.init(canvas); canvasEditor.use(DringPlugin); @@ -153,39 +118,104 @@ const initFabric = () => { /** * @设备点位 */ +// 新增点位 function addLocal() { deviceSettingAddRef.value?.openDialog(); } - +// 编辑点位 +function editLocal() { + deviceSettingAddRef.value?.openDialog(); +} +// 删除点位 +function deleteLocal() {} +// 查看获取点位 function fetchLocalList() { - localList.value = [ - // { - // id: "1", - // name: "点位1", - // type: "1", - // x: 100, - // y: 100, - // width: 100, - // height: 100, - // color: "#ff0000", - // text: "点位1", - // textX: 100, - // textY: 100, - // textFont: "20px Arial", - // textFill: "#000000", - // textStroke: "#ffffff", - // textStrokeWidth: 1, - // textBackgroundColor: "#ffffff" - // } + pointList.value = [ + { + id: "001", + name: "点位1", + imgUrl: + "https://img.cgmodel.com/image/2020/1010/big/1537169-1390622992.jpg", + deviceList: [] + }, + { + id: "002", + name: "点位2", + imgUrl: + "https://p3.toutiaoimg.com/origin/tos-cn-i-qvj2lq49k0/0143ca57f0614e2e9e6b7695993ec648?from=pc.jpg", + deviceList: [] + }, + { + id: "003", + name: "点位3", + imgUrl: + "https://pic.rmb.bdstatic.com/bjh/down/117d26bb4bde23110da2995624fc69c3.jpeg", + deviceList: [] + } + ]; + activePointId.value = pointList.value[0].id; + activePoint.value = pointList.value[0]; + deviceList.value = [ + { + id: "1001", + name: "设备1", + type: 1 + }, + { + id: "1002", + name: "设备2", + type: 2 + }, + { + id: "1003", + name: "设备3", + type: 1 + }, + { + id: "1004", + name: "设备4", + type: 3 + } ]; } +// 切换点位 +function tabPoint(tab) { + const selectedTab = pointList.value.find(t => t.id === tab.props.name); + activePoint.value = selectedTab; + console.log(tab.props.name, "tabPoint", activePoint.value); + nextTick(() => { + initFile(); + }); +} + +// 获取设备列表 +// function fetchDeviceList() { +// // fetchDeviceList() +// deviceList.value = [ +// { +// id: "1", +// name: "设备1", +// type: 1 +// } +// ]; +// } + +// function fetchDeviceList(params) { +// deviceList.value = [ +// { +// id: "1", +// name: "设备1", +// type: 1 +// } +// ] +// } // 有点位了再初始化 watch( - () => localList.value, + () => pointList.value, () => { - console.log("localList", localList); - if (localList.value.length) { + console.log("pointList", pointList); + if (pointList.value?.length) { nextTick(() => { initFabric(); }); @@ -193,14 +223,103 @@ watch( } ); +// watch( +// () => activePoint.value, +// () => { +// console.log("activePoint", activePoint); +// if (activePoint.value?.id) { +// nextTick(() => { +// initFile(); +// }); +// } +// } +// ); + onMounted(() => { fetchLocalList(); }); - +// 发射全局事件 provide("fabric", fabric); provide("event", event); provide("canvasEditor", canvasEditor); </script> -<style lang="scss" scoped> +<template> + <div class="main_booy_container deviceSetting_wrap"> + <header class="flex items-center justify-between" v-if="state.showFabric"> + <h3>设备布点</h3> + <div> + <el-button type="primary" @click="addLocal" v-if="pointList.length" + >新建位置</el-button + > + </div> + <!-- 预览 --> + <!-- <previewCurrent /> --> + <!-- <save></save> --> + <!-- <waterMark /> --> + </header> + <div class="main_content"> + <div class="device_add_wrap" v-show="!pointList.length"> + <div class="bg_preview"> + <!-- // TODO 效果图 --> + </div> + <p class="pt-[16px] pb-[24px] pf-1 leading-[16px]"> + 本页面为数据可视化大屏中设备点位界面的配置页,通过上传设备所处区域的实拍图或平面图后,根据设备的实际位置,简单的使用拖拽等操作将设备列表中的设备与位置进行匹配,使之能够在数据可视化大屏中更加精细化而直观的了解设备的具体位置与状态。 + </p> + <div class="flex justify-center"> + <el-button type="primary" @click="addLocal">新建位置</el-button> + </div> + </div> + <div class="w-full point_detail_wrap" v-show="pointList.length"> + <el-tabs + v-model="activePointId" + class="demo-tabs" + @tab-click="tabPoint" + > + <el-tab-pane + :label="item.name" + :name="item.id" + v-for="item in pointList" + :key="item.id" + /> + </el-tabs> + <div class="flex w-full h-full"> + <!-- 左侧画布区域 --> + <div id="workspace" class="h-full deviceOfPoint_wrap"> + <div class="canvas-box"> + <!-- <div class="inside-shadow"></div> --> + <canvas + id="canvas" + :class="state.ruler ? 'design-stage-grid' : ''" + /> + <!-- <dragMode v-if="state.showFabric"></dragMode> + <zoom></zoom> --> + <!-- <mouseMenu></mouseMenu> --> + </div> + </div> + <!-- 右侧属性区域--> + <div class="right-bar" v-if="state.showFabric"> + <DeviceSelect :deviceList="deviceList" /> + <DeviceAttr /> + </div> + </div> + <div class="footer_btns"> + <el-button type="primary" @click="editLocal" v-if="pointList.length" + >编辑位置</el-button + > + <el-button + type="danger" + plain + @click="deleteLocal" + v-if="pointList.length" + >删除位置</el-button + > + </div> + </div> + </div> + <DeviceSettingAdd ref="deviceSettingAddRef" /> + </div> +</template> + +<style lang="scss"> @import url("./index.scss"); </style> diff --git a/src/views/deviceSetting/testData/bg01.json b/src/views/deviceSetting/testData/bg01.json deleted file mode 100644 index 51eeb38..0000000 --- a/src/views/deviceSetting/testData/bg01.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "version": "5.3.0", - "objects": [ - { - "type": "rect", - "version": "5.3.0", - "originX": "left", - "originY": "top", - "left": 0, - "top": 0, - "width": 1200, - "height": 900, - "fill": "rgba(255,255,255,1)", - "stroke": null, - "strokeWidth": 0, - "strokeDashArray": null, - "strokeLineCap": "butt", - "strokeDashOffset": 0, - "strokeLineJoin": "miter", - "strokeUniform": false, - "strokeMiterLimit": 4, - "scaleX": 1, - "scaleY": 1, - "angle": 0, - "flipX": false, - "flipY": false, - "opacity": 1, - "shadow": null, - "visible": true, - "backgroundColor": "", - "fillRule": "nonzero", - "paintFirst": "fill", - "globalCompositeOperation": "source-over", - "skewX": 0, - "skewY": 0, - "rx": 0, - "ry": 0, - "id": "workspace", - "selectable": false, - "hasControls": false - }, - { - "type": "image", - "version": "5.3.0", - "originX": "left", - "originY": "top", - "left": 23.2346, - "top": 23.0507, - "width": 1600, - "height": 1200, - "fill": "rgb(0,0,0)", - "stroke": null, - "strokeWidth": 0, - "strokeDashArray": null, - "strokeLineCap": "butt", - "strokeDashOffset": 0, - "strokeLineJoin": "miter", - "strokeUniform": false, - "strokeMiterLimit": 4, - "scaleX": 0.721, - "scaleY": 0.721, - "angle": 0, - "flipX": false, - "flipY": false, - "opacity": 1, - "shadow": null, - "visible": true, - "backgroundColor": "", - "fillRule": "nonzero", - "paintFirst": "fill", - "globalCompositeOperation": "source-over", - "skewX": 0, - "skewY": 0, - "cropX": 0, - "cropY": 0, - "id": "a3ab29c6-7008-49fe-abf3-edc9a47cd460", - "selectable": false, - "hasControls": false, - "evented": false, - "crossOrigin": null, - "src": "https://img.cgmodel.com/image/2020/1010/big/1537169-1390622992.jpg", - "filters": [] - } - ] -} diff --git a/src/views/deviceSetting/testData/room2.png b/src/views/deviceSetting/testData/room2.png deleted file mode 100644 index 4c23916..0000000 Binary files a/src/views/deviceSetting/testData/room2.png and /dev/null differ diff --git a/src/views/deviceSetting/testData/房间平面图 (4).png b/src/views/deviceSetting/testData/房间平面图 (4).png deleted file mode 100644 index 1928c87..0000000 Binary files a/src/views/deviceSetting/testData/房间平面图 (4).png and /dev/null differ diff --git a/src/views/deviceSetting/testData/房间平面图.png b/src/views/deviceSetting/testData/房间平面图.png deleted file mode 100644 index 0a90aa9..0000000 Binary files a/src/views/deviceSetting/testData/房间平面图.png and /dev/null differ