|
@@ -6,12 +6,28 @@
|
|
|
<div class="content-layout">
|
|
|
<div class="house-tags">
|
|
|
<h4>请选择要同步到现场图的标注:</h4>
|
|
|
- <div class="tagging-transfer">
|
|
|
+ <div
|
|
|
+ class="tagging-transfer"
|
|
|
+ v-sortable="{ handle: '.value-option' }"
|
|
|
+ ref="dragLayout"
|
|
|
+ >
|
|
|
<el-transfer
|
|
|
:titles="['所有', '需要']"
|
|
|
v-model="transferValue"
|
|
|
:data="transferSource"
|
|
|
- />
|
|
|
+ target-order="push"
|
|
|
+ >
|
|
|
+ <template #default="{ option }">
|
|
|
+ <span
|
|
|
+ :class="{ 'value-option': transferValue.includes(option.key) }"
|
|
|
+ :id="'o' + option.key"
|
|
|
+ :draggable="transferValue.includes(option.key)"
|
|
|
+ >
|
|
|
+ <span>{{ option.label }}</span>
|
|
|
+ <el-icon v-if="transferValue.includes(option.key)"><Rank /></el-icon>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-transfer>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="house-image-layout">
|
|
@@ -38,7 +54,7 @@ import {
|
|
|
FuseImageType,
|
|
|
fuseImageJoinHot,
|
|
|
} from "@/view/case/help";
|
|
|
-import { computed, onMounted, ref } from "vue";
|
|
|
+import { computed, nextTick, onMounted, ref, watchEffect } from "vue";
|
|
|
import { QuiskExpose } from "@/helper/mount";
|
|
|
|
|
|
export type FuseImage = { blob: Blob | null; taggings: CaseTagging[] };
|
|
@@ -91,6 +107,49 @@ defineExpose<QuiskExpose>({
|
|
|
onMounted(async () => {
|
|
|
taggings.value = await getCaseTaggings(props.caseId);
|
|
|
});
|
|
|
+
|
|
|
+watchEffect(async (onClanup) => {
|
|
|
+ transferValue.value.join("");
|
|
|
+ await nextTick();
|
|
|
+ const desps: (() => void)[] = [];
|
|
|
+ let repKey: number | null;
|
|
|
+ for (const key of transferValue.value) {
|
|
|
+ const $option = document.querySelector("#o" + key) as HTMLDivElement;
|
|
|
+ const startHandler = () => {
|
|
|
+ $option.classList.add("dragging");
|
|
|
+ repKey = key;
|
|
|
+
|
|
|
+ $option.addEventListener("dragend", function endHandler(ev) {
|
|
|
+ $option.classList.remove("dragging");
|
|
|
+ $option.removeEventListener("dragend", endHandler);
|
|
|
+ });
|
|
|
+ };
|
|
|
+ const dragoverHandler = (ev: Event) => ev.preventDefault();
|
|
|
+ const dropHandler = (ev: Event) => {
|
|
|
+ ev.preventDefault();
|
|
|
+ if (repKey && key !== repKey) {
|
|
|
+ const oldIndex = transferValue.value.indexOf(key);
|
|
|
+ const newIndex = transferValue.value.indexOf(repKey);
|
|
|
+ transferValue.value[newIndex] = key;
|
|
|
+ transferValue.value[oldIndex] = repKey;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ $option.addEventListener("dragstart", startHandler);
|
|
|
+ $option.addEventListener("dragover", dragoverHandler);
|
|
|
+ $option.addEventListener("drop", dropHandler);
|
|
|
+
|
|
|
+ desps.push(() => {
|
|
|
+ $option.removeEventListener("dragstart", startHandler);
|
|
|
+ $option.removeEventListener("dragover", startHandler);
|
|
|
+ $option.removeEventListener("drop", dropHandler);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ onClanup(() => {
|
|
|
+ desps.forEach((desp) => desp());
|
|
|
+ });
|
|
|
+});
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
@@ -189,4 +248,25 @@ onMounted(async () => {
|
|
|
.icon {
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
+
|
|
|
+.value-option {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ span {
|
|
|
+ flex: 1;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ }
|
|
|
+
|
|
|
+ i {
|
|
|
+ flex: 0 0 auto;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|
|
|
+<style>
|
|
|
+.value-option.dragging {
|
|
|
+ opacity: 0.5;
|
|
|
+}
|
|
|
</style>
|