huangxw 4 месяцев назад
Родитель
Сommit
a0a3b73b52

+ 1 - 0
package.json

@@ -24,6 +24,7 @@
   },
   "dependencies": {
     "@element-plus/icons-vue": "2.3.1",
+    "@gausszhou/vue3-drag-resize-rotate": "^3.0.2",
     "@highlightjs/vue-plugin": "2.1.0",
     "@vueup/vue-quill": "1.2.0",
     "@vueuse/core": "11.3.0",

+ 55 - 0
src/components/DragResizeRotate/DragResizeRotate.vue

@@ -0,0 +1,55 @@
+<template>
+    <VueDragResizeRotate :x="drapJson.x" :y="drapJson.y" :w="drapJson.w" :h="drapJson.h" :r="drapJson.r" :parent="true" @resizing="onResize" @resizestop="onResizeStop" @activated="onActivated" @deactivated="onDeactivated" @dragging="onDrag" @dragstop="onDragStop">
+        <div class="w-100% h-100% d-flex a-c j-c">点击事件区域</div>
+    </VueDragResizeRotate>
+</template>
+<script setup lang="ts" name="ptpl-edit-index">
+import { propTypes } from '@/utils/propTypes';
+import VueDragResizeRotate from '@gausszhou/vue3-drag-resize-rotate';
+import '@gausszhou/vue3-drag-resize-rotate/lib/bundle.esm.css';
+const prop = defineProps({
+    modelValue: propTypes.any.def({
+        id: ''
+    })
+});
+const emit = defineEmits([
+    'update:modelValue',
+    'activated',
+    'deactivated',
+    'dragging',
+    'dragstop',
+    'resizing',
+    'resizestop'
+]);
+const drapJson = ref({
+    x: 0,
+    y: 0,
+    w: 100,
+    h: 100,
+    r: 0,
+    ...prop.modelValue
+});
+const onActivated = () => {
+    emit('activated');
+};
+const onDeactivated = () => {
+    emit('deactivated');
+};
+const onDrag = (left: number, top: number) => {
+    emit('dragging', left, top);
+};
+const onDragStop = (left: number, top: number) => {
+    emit('update:modelValue', { ...drapJson.value, x: left, y: top });
+    emit('dragstop', left, top);
+};
+const onResize = (x: number, y: number, width: number, height: number) => {
+    emit('resizing', x, y, width, height);
+};
+const onResizeStop = (x: number, y: number, width: number, height: number) => {
+    emit('update:modelValue', { ...drapJson.value, x, y, w: width, h: height });
+    emit('resizestop', x, y, width, height);
+};
+watch(() => prop.modelValue, (newVal) => {
+    drapJson.value = { ...drapJson.value, ...newVal };
+});
+</script>

+ 96 - 0
src/components/TelViewTem/TelViewTem.vue

@@ -0,0 +1,96 @@
+<template>
+    <div class="tel-view-tem" :style="{ width: `${width}px`, height: `${height}px`, background: bgColor, position: 'relative', userSelect: 'none' }" @mousedown="onMouseDown">
+        <!-- 拖动选区样式 -->
+        <div v-if="isDragging" class="drag-area" :style="dragAreaStyle"></div>
+        <slot></slot>
+    </div>
+</template>
+
+<script setup lang="ts">
+import { ref, computed } from 'vue';
+import { propTypes } from '@/utils/propTypes';
+
+const props = defineProps({
+  width: propTypes.number.def(750),
+  height: propTypes.number.def(1000),
+  bgColor: propTypes.string.def('#fff'),
+  enableDraw: propTypes.bool.def(true) // 新增开关属性
+});
+
+const emit = defineEmits(['selectArea']);
+
+const isDragging = ref(false);
+const startPoint = ref({ x: 0, y: 0 });
+const endPoint = ref({ x: 0, y: 0 });
+
+const dragAreaStyle = computed(() => {
+  const x = Math.min(startPoint.value.x, endPoint.value.x);
+  const y = Math.min(startPoint.value.y, endPoint.value.y);
+  const w = Math.abs(endPoint.value.x - startPoint.value.x);
+  const h = Math.abs(endPoint.value.y - startPoint.value.y);
+  return {
+    position: 'absolute',
+    left: `${x}px`,
+    top: `${y}px`,
+    width: `${w}px`,
+    height: `${h}px`,
+    border: '1px dashed #409eff',
+    background: 'rgba(64,158,255,0.1)',
+    pointerEvents: 'none',
+    zIndex: 10,
+  };
+});
+
+function onMouseDown(e: MouseEvent) {
+  if (!props.enableDraw) return; // 根据开关属性决定是否允许绘制
+  if (e.button !== 0) return;
+  const rect = (e.target as HTMLElement).getBoundingClientRect();
+  startPoint.value = {
+    x: e.clientX - rect.left,
+    y: e.clientY - rect.top,
+  };
+  endPoint.value = { ...startPoint.value };
+  isDragging.value = true;
+
+  window.addEventListener('mousemove', onMouseMove);
+  window.addEventListener('mouseup', onMouseUp);
+}
+
+function onMouseMove(e: MouseEvent) {
+  if (!isDragging.value) return;
+  const rect = (e.target as HTMLElement).closest('.tel-view-tem')?.getBoundingClientRect();
+  if (!rect) return;
+  endPoint.value = {
+    x: e.clientX - rect.left,
+    y: e.clientY - rect.top,
+  };
+}
+
+function onMouseUp() {
+  if (!isDragging.value) return;
+  isDragging.value = false;
+  emit('selectArea', {
+    start: { ...startPoint.value },
+    end: { ...endPoint.value },
+    rect: {
+      x: Math.min(startPoint.value.x, endPoint.value.x),
+      y: Math.min(startPoint.value.y, endPoint.value.y),
+      w: Math.abs(endPoint.value.x - startPoint.value.x),
+      h: Math.abs(endPoint.value.y - startPoint.value.y),
+    },
+  });
+  window.removeEventListener('mousemove', onMouseMove);
+  window.removeEventListener('mouseup', onMouseUp);
+}
+</script>
+
+<style scoped lang="scss">
+.tel-view-tem {
+  box-sizing: border-box;
+  overflow: hidden;
+  position: relative;
+}
+.drag-area {
+  transition: none;
+}
+</style>

+ 0 - 0
src/store/modules/sideNum.ts


+ 0 - 0
src/utils/httpRequests.ts


+ 0 - 0
src/views/appointment-record/experience/index.vue


+ 39 - 0
src/views/training/ptpl/edit/index.vue

@@ -0,0 +1,39 @@
+<template>
+    <div>
+        <TelViewTem @selectArea="selectArea" :enableDraw="enableDraw">
+            <template v-for="(item, index) in form?.btns" :key="index">
+                <DragResizeRotate v-model="form.btns[index]" @activated="activated" @deactivated="deactivated"></DragResizeRotate>
+            </template>
+        </TelViewTem>
+        <el-button @click="addInfo">新增</el-button>
+        <el-button @click="clickInfo">信息</el-button>
+    </div>
+</template>
+<script setup lang="ts" name="ptpl-edit-index">
+const form = ref<any>({
+    btns: [
+        { id: '2231321321' }
+    ]
+})
+const enableDraw = ref(true);
+const addInfo = () => {
+    form.value.btns.push({ id: new Date().getTime() + '_btn_drap' });
+}
+const selectArea = (area: any) => {
+    if (area.rect.w < 20 || area.rect.h < 20) {
+        return;
+    }
+    form.value.btns.push({ id: new Date().getTime() + '_btn_drap', ...area.rect });
+}
+const activated = () => {
+    console.log('activated');
+    enableDraw.value = false;
+}
+const deactivated = () => {
+    console.log('deactivated');
+    enableDraw.value = true;
+}
+const clickInfo = () => {
+    console.log(form.value);
+}
+</script>

+ 3 - 0
src/views/training/ptpl/list/index.vue

@@ -0,0 +1,3 @@
+<template>
+    <div></div>
+</template>