|
@@ -80,7 +80,6 @@
|
|
|
class="scroll-bar-right-16"
|
|
|
>
|
|
|
<HcDataTree
|
|
|
- is-form-date
|
|
|
is-load-menu
|
|
|
:datas="searchTreeData"
|
|
|
:is-mark="TreeMark"
|
|
@@ -89,7 +88,7 @@
|
|
|
is-type
|
|
|
:auto-expand-keys="TreeAutoExpandKeys"
|
|
|
default-expand-all
|
|
|
-
|
|
|
+ is-form-date
|
|
|
@node-tap="wbsElTreeClick"
|
|
|
@menu-tap="ElTreeMenuClick"
|
|
|
@load-menu="loadMenu"
|
|
@@ -101,14 +100,15 @@
|
|
|
>
|
|
|
<HcLazyTree
|
|
|
ref="wbstree"
|
|
|
+ is-form-date
|
|
|
is-load-menu
|
|
|
:auto-expand-keys="TreeAutoExpandKeys"
|
|
|
:is-mark="TreeMark"
|
|
|
:menus="ElTreeMenu"
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- is-counts is-type show-checkbox check-strictly is-form-date
|
|
|
+ is-counts
|
|
|
+ is-type
|
|
|
+ show-checkbox
|
|
|
+ check-strictly
|
|
|
@load="treeLoadNode"
|
|
|
@menu-tap="ElTreeMenuClick"
|
|
|
@node-loading="ElTreeNodeLoading"
|
|
@@ -169,7 +169,9 @@
|
|
|
<HcTooltip keys="wbs_views_sort_btn">
|
|
|
<el-button
|
|
|
v-if="nodeDataInfo?.nodeClass !== 2"
|
|
|
- :disabled="ListItemDatas.length <= 0 || (nodeDataInfo?.colorStatus !== 2 && nodeDataInfo?.colorStatus !== 1)"
|
|
|
+ :disabled="ListItemDatas.length <= 0 || (nodeDataInfo?.colorStatus !== 1 && nodeDataInfo?.colorStatus !== 2)"
|
|
|
+
|
|
|
+
|
|
|
hc-btn
|
|
|
type="primary"
|
|
|
@click="sortFormClick"
|
|
@@ -1234,9 +1236,9 @@
|
|
|
/>
|
|
|
|
|
|
<!-- 查看附件 -->
|
|
|
-
|
|
|
<hc-new-dialog
|
|
|
v-model="attachmentModal"
|
|
|
+
|
|
|
is-table
|
|
|
title="附件列表"
|
|
|
widths="780px"
|
|
@@ -1249,12 +1251,14 @@
|
|
|
<span class="text-orange">按住鼠标拖动文件可进行附件列表排序</span>
|
|
|
</div>
|
|
|
<div
|
|
|
- v-for="(item, index) in attachmentList"
|
|
|
+ v-for="item in attachmentList"
|
|
|
:key="item.id"
|
|
|
class="hc-attachment-card"
|
|
|
+ :data-node-id="item.id"
|
|
|
>
|
|
|
<div class="hc-attachment-header">
|
|
|
{{ item?.nodeName }}
|
|
|
+ <!-- <el-button type="success" :loading="saveFileOrderLoad" style="float:right" @click="saveFileOrder">确定排序</el-button> -->
|
|
|
</div>
|
|
|
<div
|
|
|
:ref="setAttachmentListRef"
|
|
@@ -1264,10 +1268,9 @@
|
|
|
v-for="item1 in item.fileList"
|
|
|
:key="item1.id"
|
|
|
class="hc-attachment-item"
|
|
|
- :data-id="item1.id"
|
|
|
>
|
|
|
<div class="hc-attachment-file-name">
|
|
|
- <HcIcon name="drag-move-2" class="drag-handle text-blue" />
|
|
|
+ <HcIcon name="drag-move-2" class="text-blue" />
|
|
|
<HcIcon name="attachment" class="ml-2" />
|
|
|
<div class="name">{{ item1?.name }}</div>
|
|
|
</div>
|
|
@@ -1300,17 +1303,9 @@
|
|
|
</div>
|
|
|
<template #footer>
|
|
|
<el-button @click="attachmentModal = false">关闭</el-button>
|
|
|
- <el-button
|
|
|
- type="primary"
|
|
|
- :loading="saveFileOrderLoad"
|
|
|
- :disabled="attachmentList.length === 0"
|
|
|
- @click="saveFileOrder"
|
|
|
- >
|
|
|
- 确定排序
|
|
|
- </el-button>
|
|
|
+ <el-button type="primary" :loading="saveFileOrderLoad" :disabled="attachmentList.length === 0" @click="saveFileOrder">确定排序</el-button>
|
|
|
</template>
|
|
|
</hc-new-dialog>
|
|
|
-
|
|
|
<!-- 上传文件 -->
|
|
|
<hc-new-dialog
|
|
|
v-model="uploadModal"
|
|
@@ -1425,7 +1420,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, watch } from 'vue'
|
|
|
+import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
|
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
import { useAppStore } from '~src/store'
|
|
|
import { HcIsButton } from '~src/plugins/IsButtons'
|
|
@@ -1549,16 +1544,8 @@ onMounted(() => {
|
|
|
getDictionaryApi()
|
|
|
getStandardTypeOptions()
|
|
|
getMajorDataTypeOptions()
|
|
|
- nextTick(() => {
|
|
|
- initDragAndDrop()
|
|
|
- })
|
|
|
-})
|
|
|
-// 组件卸载前清理事件
|
|
|
-onBeforeUnmount(() => {
|
|
|
- attachmentListRefs.value.forEach(container => {
|
|
|
- container.removeEventListener('dragover', () => {})
|
|
|
- })
|
|
|
})
|
|
|
+
|
|
|
//身份按钮切换数据
|
|
|
const authBtnTabKey = ref('1')
|
|
|
|
|
@@ -2026,7 +2013,7 @@ const setTreeMenuDataClick = ({ key, node, data }) => {
|
|
|
window?.$message?.warning('该节点已存在上报数据,不允许删除')
|
|
|
}
|
|
|
} else if (key === 'sort') {
|
|
|
-
|
|
|
+
|
|
|
let nodes = [],
|
|
|
childNodes = []
|
|
|
if (tabKey === 'tree') {
|
|
@@ -3137,80 +3124,40 @@ const getAttachmentList = async () => {
|
|
|
const attachmentListRefs = ref([])
|
|
|
const sortableInstances = ref([])
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-// 设置附件列表的ref
|
|
|
const setAttachmentListRef = (el) => {
|
|
|
if (el) {
|
|
|
attachmentListRefs.value.push(el)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 初始化拖拽功能
|
|
|
-const initDragAndDrop = () => {
|
|
|
- attachmentListRefs.value.forEach((container, index) => {
|
|
|
- const items = container.querySelectorAll('.hc-attachment-item')
|
|
|
-
|
|
|
- items.forEach((item) => {
|
|
|
- item.draggable = true
|
|
|
-
|
|
|
- // 拖拽开始事件
|
|
|
- item.addEventListener('dragstart', (e) => {
|
|
|
- e.dataTransfer.setData('text/plain', item.dataset.id)
|
|
|
- item.classList.add('dragging')
|
|
|
- setTimeout(() => {
|
|
|
- item.style.display = 'none'
|
|
|
- }, 0)
|
|
|
- })
|
|
|
+// 初始化拖拽排序
|
|
|
+const initSortable = () => {
|
|
|
+ nextTick(() => {
|
|
|
+ attachmentList.value.forEach((item) => {
|
|
|
+ // 更可靠的DOM查找方式
|
|
|
+ const container = document.querySelector(`.hc-attachment-card[data-node-id="${item.id}"] .hc-attachment-content`)
|
|
|
|
|
|
- // 拖拽结束事件
|
|
|
- item.addEventListener('dragend', () => {
|
|
|
- items.forEach(i => {
|
|
|
- i.classList.remove('dragging')
|
|
|
- i.style.display = ''
|
|
|
+ if (container && !sortableInstances.value[item.id]) {
|
|
|
+ sortableInstances.value[item.id] = Sortable.create(container, {
|
|
|
+ animation: 150,
|
|
|
+ handle: '.hc-attachment-file-name',
|
|
|
+ onEnd: (evt) => {
|
|
|
+ // 确保能正确找到对应的item
|
|
|
+ const currentItem = attachmentList.value.find(i => i.id === item.id)
|
|
|
+ if (!currentItem) return
|
|
|
+
|
|
|
+ const newFileList = [...currentItem.fileList]
|
|
|
+ const [movedItem] = newFileList.splice(evt.oldIndex, 1)
|
|
|
+ newFileList.splice(evt.newIndex, 0, movedItem)
|
|
|
+
|
|
|
+ // 使用Vue的响应式更新
|
|
|
+ currentItem.fileList = newFileList
|
|
|
+ },
|
|
|
})
|
|
|
-
|
|
|
- // 获取新的顺序
|
|
|
- const newOrder = Array.from(container.querySelectorAll('.hc-attachment-item')).map(item => item.dataset.id)
|
|
|
-
|
|
|
- // 更新 attachmentList.value 中对应项的 fileList 顺序
|
|
|
- const attachment = attachmentList.value[index]
|
|
|
- if (attachment) {
|
|
|
- attachment.fileList = attachment.fileList.sort((a, b) => newOrder.indexOf(a.id) - newOrder.indexOf(b.id))
|
|
|
- }
|
|
|
- })
|
|
|
- })
|
|
|
-
|
|
|
- // 拖拽经过事件
|
|
|
- container.addEventListener('dragover', (e) => {
|
|
|
- e.preventDefault()
|
|
|
- const draggingItem = container.querySelector('.dragging')
|
|
|
- const afterElement = getDragAfterElement(container, e.clientY)
|
|
|
-
|
|
|
- if (afterElement) {
|
|
|
- container.insertBefore(draggingItem, afterElement)
|
|
|
- } else {
|
|
|
- container.appendChild(draggingItem)
|
|
|
}
|
|
|
})
|
|
|
})
|
|
|
}
|
|
|
-// 获取拖拽后应该放置的位置
|
|
|
-const getDragAfterElement = (container, y) => {
|
|
|
- const draggableElements = [...container.querySelectorAll('.hc-attachment-item:not(.dragging)')]
|
|
|
-
|
|
|
- return draggableElements.reduce((closest, child) => {
|
|
|
- const box = child.getBoundingClientRect()
|
|
|
- const offset = y - box.top - box.height / 2
|
|
|
-
|
|
|
- if (offset < 0 && offset > closest.offset) {
|
|
|
- return { element: child, offset: offset }
|
|
|
- } else {
|
|
|
- return closest
|
|
|
- }
|
|
|
- }, { offset: Number.NEGATIVE_INFINITY }).element
|
|
|
-}
|
|
|
// 销毁 Sortable 实例
|
|
|
const destroySortableInstances = () => {
|
|
|
sortableInstances.value.forEach(instance => {
|
|
@@ -3224,7 +3171,7 @@ watch(attachmentModal, (newVal) => {
|
|
|
if (!newVal) {
|
|
|
destroySortableInstances() // 关闭弹窗时销毁 Sortable 实例
|
|
|
} else {
|
|
|
- initDragAndDrop() // 打开弹窗时初始化 Sortable
|
|
|
+ initSortable() // 打开弹窗时初始化 Sortable
|
|
|
}
|
|
|
})
|
|
|
onUnmounted(() => {
|
|
@@ -3235,21 +3182,20 @@ const saveFileOrderLoad = ref(false)
|
|
|
const saveFileOrder = async () => {
|
|
|
|
|
|
saveFileOrderLoad.value = true
|
|
|
- console.log(attachmentList.value, 'attachmentList.value')
|
|
|
|
|
|
const { error, code, msg } = await wbsApi.sortPdf( attachmentList.value)
|
|
|
saveFileOrderLoad.value = false
|
|
|
if (!error && code === 200) {
|
|
|
window?.$message?.success(msg)
|
|
|
getAttachmentList()
|
|
|
- initDragAndDrop()
|
|
|
+ initSortable()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 监听attachmentList变化时初始化拖拽
|
|
|
watch(() => attachmentList.value, () => {
|
|
|
nextTick(()=>{
|
|
|
- initDragAndDrop()
|
|
|
+ initSortable()
|
|
|
})
|
|
|
}, { deep: true })
|
|
|
//预览
|
|
@@ -3909,51 +3855,57 @@ html.theme-dark {
|
|
|
}
|
|
|
</style>
|
|
|
|
|
|
-<style scoped>
|
|
|
-.hc-attachment-content {
|
|
|
- min-height: 20px;
|
|
|
- padding: 10px;
|
|
|
- background-color: #f5f7fa;
|
|
|
- border-radius: 4px;
|
|
|
+<style lang="scss" scoped>
|
|
|
+/* 新增拖拽排序相关样式 */
|
|
|
+.sortable-ghost {
|
|
|
+ opacity: 0.5;
|
|
|
+ background: #f5f5f5;
|
|
|
}
|
|
|
|
|
|
.hc-attachment-item {
|
|
|
+ transition: all 0.3s;
|
|
|
+ cursor: move;
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
- padding: 10px;
|
|
|
+ padding: 12px;
|
|
|
margin-bottom: 8px;
|
|
|
- background-color: white;
|
|
|
- border: 1px solid #ebeef5;
|
|
|
+ background: #fff;
|
|
|
border-radius: 4px;
|
|
|
- cursor: move;
|
|
|
- transition: all 0.3s;
|
|
|
-}
|
|
|
-
|
|
|
-.hc-attachment-item:hover {
|
|
|
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
|
-}
|
|
|
-
|
|
|
-.hc-attachment-item.dragging {
|
|
|
- opacity: 0.5;
|
|
|
- background-color: #f5f7fa;
|
|
|
+ border: 1px solid #ebeef5;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-.hc-attachment-file-name {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- flex: 1;
|
|
|
+.hc-attachment-content {
|
|
|
+ min-height: 20px;
|
|
|
}
|
|
|
|
|
|
-.hc-attachment-file-name .name {
|
|
|
- margin-left: 8px;
|
|
|
- max-width: 300px;
|
|
|
- overflow: hidden;
|
|
|
- text-overflow: ellipsis;
|
|
|
- white-space: nowrap;
|
|
|
-}
|
|
|
+/* 原有样式保持不变 */
|
|
|
+.hc-attachment-card {
|
|
|
+ margin-bottom: 16px;
|
|
|
+
|
|
|
+ .hc-attachment-header {
|
|
|
+ font-weight: bold;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ padding-left: 8px;
|
|
|
+ border-left: 3px solid #409eff;
|
|
|
|
|
|
-.drag-handle {
|
|
|
- cursor: move;
|
|
|
+ }
|
|
|
+
|
|
|
+ .hc-attachment-file-name {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .name {
|
|
|
+ margin-left: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .hc-attachment-btn-box {
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|