|
@@ -6,6 +6,7 @@
|
|
|
append-to-body
|
|
|
:close-on-click-modal="false"
|
|
|
|
|
|
+
|
|
|
>
|
|
|
|
|
|
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
|
|
@@ -130,12 +131,15 @@
|
|
|
:visible.sync="sortDialogVisible"
|
|
|
width="50%"
|
|
|
append-to-body
|
|
|
+ @close="handleSortDialogClose"
|
|
|
|
|
|
>
|
|
|
<el-table
|
|
|
:data="sortedTableData"
|
|
|
style="width: 100%"
|
|
|
- :key="sortedTableDataKey"
|
|
|
+ :key="sortedTableDataKey"
|
|
|
+ ref="sortTable"
|
|
|
+ row-key="id"
|
|
|
>
|
|
|
<el-table-column label="序号" type="index" width="50"></el-table-column>
|
|
|
<!-- 新增的快速排序列 -->
|
|
@@ -172,17 +176,24 @@
|
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" width="150">
|
|
|
<template slot-scope="scope">
|
|
|
- <el-button
|
|
|
- type="text"
|
|
|
- icon="el-icon-top"
|
|
|
- @click="handleSortUp(scope.$index)"
|
|
|
- style="margin-right: 5px;"
|
|
|
- ></el-button>
|
|
|
- <el-button
|
|
|
- type="text"
|
|
|
- icon="el-icon-bottom"
|
|
|
- @click="handleSortDown(scope.$index)"
|
|
|
- ></el-button>
|
|
|
+ <div style="display: flex; align-items: center;">
|
|
|
+ <!-- 拖拽手柄 -->
|
|
|
+ <i class="el-icon-rank drag-handle"
|
|
|
+ style="cursor: move; margin-right: 10px; color: #409EFF;"></i>
|
|
|
+
|
|
|
+ <!-- 上下移动按钮 -->
|
|
|
+ <el-button
|
|
|
+ type="text"
|
|
|
+ icon="el-icon-top"
|
|
|
+ @click="handleSortUp(scope.$index)"
|
|
|
+ style="margin-right: 5px;"
|
|
|
+ ></el-button>
|
|
|
+ <el-button
|
|
|
+ type="text"
|
|
|
+ icon="el-icon-bottom"
|
|
|
+ @click="handleSortDown(scope.$index)"
|
|
|
+ ></el-button>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
@@ -202,6 +213,7 @@
|
|
|
<script>
|
|
|
import {getTrialNumberRule,save,update,remove,sort,submitList } from "@/api/ruleManage/codeRule.js";
|
|
|
import { getDictionary } from "@/api/system/dict";
|
|
|
+import Sortable from 'sortablejs';
|
|
|
export default {
|
|
|
name: 'FileRuleDialog',
|
|
|
|
|
@@ -232,13 +244,24 @@ export default {
|
|
|
sortedTableData: [], // 排序弹窗的表格数据,为tableData的深拷贝
|
|
|
sortLoad: false, // 排序保存按钮的loading状态
|
|
|
sortedTableDataKey: 0, // 控制排序弹窗表格的key,用于强制更新
|
|
|
+ sortable: null,
|
|
|
+ isDragging: false
|
|
|
|
|
|
|
|
|
}
|
|
|
},
|
|
|
-mounted(){
|
|
|
-
|
|
|
-},
|
|
|
+ watch: {
|
|
|
+ // 监听对话框显示状态
|
|
|
+ sortDialogVisible(val) {
|
|
|
+ if (val) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.initSortable();
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.destroySortable();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
methods: {
|
|
|
|
|
|
|
|
@@ -247,6 +270,7 @@ mounted(){
|
|
|
this.projectId = pid
|
|
|
this.getTableData()
|
|
|
this.getNumberOptions()
|
|
|
+
|
|
|
},
|
|
|
|
|
|
handleClick(tab, event) {
|
|
@@ -264,6 +288,14 @@ mounted(){
|
|
|
this.$set(item, 'sortOrder', index + 1);
|
|
|
});
|
|
|
this.sortDialogVisible = true; // 显示排序弹窗
|
|
|
+ this.$nextTick(()=>{
|
|
|
+ this.initSortable(); // 初始化拖拽排序
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+ },
|
|
|
+ handleSortDialogClose(){
|
|
|
+ this.destroySortable();
|
|
|
},
|
|
|
|
|
|
|
|
@@ -316,6 +348,55 @@ mounted(){
|
|
|
});
|
|
|
|
|
|
this.sortedTableData = newData;
|
|
|
+ },
|
|
|
+ // 初始化拖拽排序
|
|
|
+ // 初始化拖拽排序
|
|
|
+ initSortable() {
|
|
|
+ this.destroySortable(); // 先销毁旧的实例
|
|
|
+
|
|
|
+ const table = this.$refs.sortTable.$el.querySelector('.el-table__body-wrapper tbody');
|
|
|
+ if (!table) return;
|
|
|
+
|
|
|
+ this.sortable = new Sortable(table, {
|
|
|
+ animation: 150,
|
|
|
+ handle: '.drag-handle',
|
|
|
+ ghostClass: 'sortable-ghost',
|
|
|
+ onStart: () => {
|
|
|
+ this.isDragging = true;
|
|
|
+ },
|
|
|
+ onEnd: ({ newIndex, oldIndex }) => {
|
|
|
+ if (newIndex === oldIndex) return;
|
|
|
+
|
|
|
+ // 更安全的移动方式
|
|
|
+ const newArray = [...this.sortedTableData]; // 创建副本
|
|
|
+ const [movedItem] = newArray.splice(oldIndex, 1);
|
|
|
+ newArray.splice(newIndex, 0, movedItem);
|
|
|
+
|
|
|
+ // 一次性更新数组
|
|
|
+ this.sortedTableData = newArray;
|
|
|
+
|
|
|
+ // 更新序号
|
|
|
+ this.updateSortOrders();
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 安全销毁Sortable实例
|
|
|
+ destroySortable() {
|
|
|
+ if (this.sortable) {
|
|
|
+ this.sortable.destroy();
|
|
|
+ this.sortable = null;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 更新所有行的排序序号
|
|
|
+ updateSortOrders() {
|
|
|
+ const newData = this.sortedTableData.map((item, index) => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ sortOrder: index + 1
|
|
|
+ };
|
|
|
+ });
|
|
|
+ this.sortedTableData = newData;
|
|
|
+
|
|
|
},
|
|
|
sortSave(){
|
|
|
this.sortLoad = true;
|
|
@@ -540,6 +621,20 @@ mounted(){
|
|
|
.input-error {
|
|
|
border-color: red;
|
|
|
}
|
|
|
+/* 拖拽时的样式效果 */
|
|
|
+.sortable-ghost {
|
|
|
+ opacity: 0.5;
|
|
|
+ background: #c8ebfb;
|
|
|
+}
|
|
|
+
|
|
|
+/* 拖拽手柄样式 */
|
|
|
+.drag-handle {
|
|
|
+ cursor: move;
|
|
|
+ transition: color 0.2s;
|
|
|
+}
|
|
|
+.drag-handle:hover {
|
|
|
+ color: #409EFF;
|
|
|
+}
|
|
|
</style>
|
|
|
<style>
|
|
|
.input-error{
|
|
@@ -547,4 +642,4 @@ mounted(){
|
|
|
border-color: red;
|
|
|
}
|
|
|
}
|
|
|
-</style>
|
|
|
+</style>
|