feat:我的成绩-增加拖动功能

This commit is contained in:
zhouwentao 2026-01-06 20:42:34 +08:00
parent 431f496b6e
commit 6717ff9bae
3 changed files with 133 additions and 11 deletions

View File

@ -19,6 +19,7 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"sass": "^1.75.0", "sass": "^1.75.0",
"sortablejs": "^1.15.6",
"swiper": "^7.4.1", "swiper": "^7.4.1",
"vite-vue": "file:", "vite-vue": "file:",
"vue": "^3.2.37", "vue": "^3.2.37",

View File

@ -38,6 +38,9 @@ importers:
sass: sass:
specifier: ^1.75.0 specifier: ^1.75.0
version: 1.94.2 version: 1.94.2
sortablejs:
specifier: ^1.15.6
version: 1.15.6
swiper: swiper:
specifier: ^7.4.1 specifier: ^7.4.1
version: 7.4.1 version: 7.4.1
@ -1575,6 +1578,9 @@ packages:
resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
sortablejs@1.15.6:
resolution: {integrity: sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A==}
source-map-js@1.2.1: source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -3508,6 +3514,8 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
sortablejs@1.15.6: {}
source-map-js@1.2.1: {} source-map-js@1.2.1: {}
source-map-resolve@0.5.3: source-map-resolve@0.5.3:

View File

@ -313,6 +313,18 @@
<div class="flex-item-2 pl-10"><el-button @click="handlerAutoSortVolunteer">智能排序</el-button></div> <div class="flex-item-2 pl-10"><el-button @click="handlerAutoSortVolunteer">智能排序</el-button></div>
</div> --> </div> -->
</div> </div>
<!-- [修改] 在这里增加保存按钮的显示逻辑 -->
<div class="flex-item-4 pl-20 pr-10" style="line-height: 30px;">
<div class="flexWrap" v-if="state.visible.showOrderSaveBtn">
<div class="flex-item-1" style="color: #f56c6c; font-weight: bold;">提示</div>
<div class="flex-item-4 pl-10">
<span style="font-size: 12px; color: #666; margin-right: 10px;">顺序已变更</span>
<el-button type="primary" size="default" @click="handleSaveVolunteerOrder">保存排序</el-button>
</div>
</div>
</div>
</div> </div>
<div class="flexWrap mt-15"> <div class="flexWrap mt-15">
<div class="flex-item-4 pl-10 pr-10" style="line-height: 30px"> <div class="flex-item-4 pl-10 pr-10" style="line-height: 30px">
@ -330,7 +342,10 @@
<div class="panetype" v-if="state.scoreInfo.meBatchLevel==0" :class="state.selectForm.batchPaneName==='本科批'?'panetype-active':''" @click="switchBatchPane('本科批')">本科批</div> <div class="panetype" v-if="state.scoreInfo.meBatchLevel==0" :class="state.selectForm.batchPaneName==='本科批'?'panetype-active':''" @click="switchBatchPane('本科批')">本科批</div>
<div class="panetype" v-if="state.scoreInfo.meBatchLevel<=3" :class="state.selectForm.batchPaneName==='高职高专'?'panetype-active':''" @click="switchBatchPane('高职高专')">高职高专</div> <div class="panetype" v-if="state.scoreInfo.meBatchLevel<=3" :class="state.selectForm.batchPaneName==='高职高专'?'panetype-active':''" @click="switchBatchPane('高职高专')">高职高专</div>
</div> </div>
<el-table row-draggable :data="returnVolunteerList()" height="800" style="width: 100%;"> <el-table
ref="volunteerTableRef"
row-key="id"
row-draggable :data="returnVolunteerList()" height="800" style="width: 100%; cursor: move;">
<el-table-column label="招生院校" width="190"> <el-table-column label="招生院校" width="190">
<template #default="scope"> <template #default="scope">
<div class="top-align" v-if="scope.row.schoolName"> <div class="top-align" v-if="scope.row.schoolName">
@ -704,9 +719,10 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
document.title = '模拟报志愿|' + import.meta.env.VITE_PROGRAM_TYPE; document.title = '模拟报志愿|' + import.meta.env.VITE_PROGRAM_TYPE;
import {inject,onMounted,reactive} from 'vue'; import { inject, onMounted, reactive, ref, nextTick, watch } from 'vue'; // 确保引入 ref, nextTick, watch
import Sortable from 'sortablejs'; // [新增] 引入 Sortablejs
import {checkLevel, isNull} from '@/utils/tool'; import {checkLevel, isNull} from '@/utils/tool';
import {getScore,getRulesEnrollrobabilityMenuList} from '@/axios/api'; import {getScore,getRulesEnrollrobabilityMenuList} from '@/axios/api';
import {ScoreInfoEntity} from '@/types/index'; import {ScoreInfoEntity} from '@/types/index';
@ -723,6 +739,9 @@ import { useRoute } from 'vue-router';
import VolunteerList from '../volunteer/volunteer-list.vue'; import VolunteerList from '../volunteer/volunteer-list.vue';
const route = useRoute(); const route = useRoute();
// [新增] 定义表格的 ref,用于获取 DOM
const volunteerTableRef = ref();
// 定义一个变量,可以是布尔值,也可以是空值 // 定义一个变量,可以是布尔值,也可以是空值
type myBoolean= boolean | null | undefined; type myBoolean= boolean | null | undefined;
@ -770,6 +789,7 @@ const state = reactive({
activePage:'zntj',//当前打开的子页面 {label:'一键填报',value:'yjtb'},{label:'我的订单',value:'wddd'} activePage:'zntj',//当前打开的子页面 {label:'一键填报',value:'yjtb'},{label:'我的订单',value:'wddd'}
pages:[{label:'智能推荐',value:'zntj'},{label:'我的志愿',value:'wdzy'},],//智能推荐,一键填报,我的志愿,我的订单 pages:[{label:'智能推荐',value:'zntj'},{label:'我的志愿',value:'wdzy'},],//智能推荐,一键填报,我的志愿,我的订单
visible:{ visible:{
showOrderSaveBtn: false,// 是否显示排序保存按钮
showOtherMajorDialog:false,//查看其他专业弹出层判断 showOtherMajorDialog:false,//查看其他专业弹出层判断
showOtherVolunteerDialog:false,//切换志愿表 showOtherVolunteerDialog:false,//切换志愿表
switchVolunteerDialog:false,//切换志愿顺序 switchVolunteerDialog:false,//切换志愿顺序
@ -1113,9 +1133,7 @@ function getVolunteerDetail(){
let e = null let e = null
for(let i=1;i<=64;i++){ for(let i=1;i<=64;i++){
e = volunteeZhuanOfIndexsMap.get(i) e = volunteeZhuanOfIndexsMap.get(i)
if(!e){ if(e){
volunteerZhuanList.push({indexs:i})
}else{
volunteerZhuanList.push(e) volunteerZhuanList.push(e)
} }
} }
@ -1125,14 +1143,11 @@ function getVolunteerDetail(){
let volunteerBenList=[] as any let volunteerBenList=[] as any
for(let i=1;i<=64;i++){ for(let i=1;i<=64;i++){
e = volunteerBenOfIndexsMap.get(i) e = volunteerBenOfIndexsMap.get(i)
if(!e){ if(e){
volunteerBenList.push({indexs:i})
}else{
volunteerBenList.push(e) volunteerBenList.push(e)
} }
} }
state.volunteerInfo.volunteerBenList = volunteerBenList state.volunteerInfo.volunteerBenList = volunteerBenList
} }
}).catch((error: any) => { }).catch((error: any) => {
console.log(error); console.log(error);
@ -1163,7 +1178,6 @@ function returnStorgeVolunteerIndex(majorInfo:any){
//选择该专业 //选择该专业
function selectVolunteer(majorInfo:any){ function selectVolunteer(majorInfo:any){
console.log('aa') console.log('aa')
let a = '-'
let key = majorInfo.id let key = majorInfo.id
//majorInfo.schoolCode+a+majorInfo.batch+a+majorInfo.majorCode+a+majorInfo.majorName+a+majorInfo.enrollmentCode //majorInfo.schoolCode+a+majorInfo.batch+a+majorInfo.majorCode+a+majorInfo.majorName+a+majorInfo.enrollmentCode
let valuesArray = [] let valuesArray = []
@ -1287,6 +1301,7 @@ function cancelSelectVolunteer(majorInfo:any){
let key = majorInfo.id let key = majorInfo.id
deleteVolunteerMapByKey(null,key) deleteVolunteerMapByKey(null,key)
} }
//模拟志愿列表 //模拟志愿列表
function getRecommendVolunteerList(){ function getRecommendVolunteerList(){
//处理真正要查询的批次 //处理真正要查询的批次
@ -1600,6 +1615,92 @@ function returnVolunteerList(){
state.selectForm.batchPaneName==='本科批'?state.volunteerInfo.volunteerBenList: state.selectForm.batchPaneName==='本科批'?state.volunteerInfo.volunteerBenList:
state.volunteerInfo.volunteerZhuanList; state.volunteerInfo.volunteerZhuanList;
} }
// [新增] 初始化拖拽功能
const initSortable = () => {
// 确保表格渲染后再初始化
nextTick(() => {
const tableEl = volunteerTableRef.value?.$el;
if (!tableEl) return;
// 获取 tbody 元素
const tbody = tableEl.querySelector('.el-table__body-wrapper tbody');
if (tbody) {
Sortable.create(tbody, {
animation: 150, // 动画时间
handle: '.el-table__row', // 设置整行皆可拖拽
onEnd: ({ newIndex, oldIndex }: any) => {
if (newIndex === oldIndex) return;
// 1. 获取当前列表的引用
const currentList = returnVolunteerList();
// 2. 移动数据:从旧位置删除,插入新位置
const currRow = currentList.splice(oldIndex, 1)[0];
currentList.splice(newIndex, 0, currRow);
// 3. 重算 indexs (志愿序号),确保 UI 上的 "志愿1, 志愿2" 显示正确
currentList.forEach((item: any, index: number) => {
item.indexs = index + 1;
});
// 4. 显示保存按钮
state.visible.showOrderSaveBtn = true;
// 提示用户
// ElMessage.info('顺序已调整,请点击保存生效');
}
});
}
});
};
// [新增] 监听 activePage 变化,当切换到 'wdzy' (我的志愿) 时初始化拖拽
watch(() => state.activePage, (newVal) => {
if (newVal === 'wdzy') {
initSortable();
}
});
// [新增] 监听批次切换,切换批次后重新初始化拖拽(防止DOM重绘导致失效)
watch(() => state.selectForm.batchPaneName, () => {
if (state.activePage === 'wdzy') {
initSortable();
}
});
// [新增] 保存排序事件
const handleSaveVolunteerOrder = () => {
const currentList = returnVolunteerList();
// 提取需要的参数,通常只需要 id 和新的 indexs
const sortData = currentList.map((item: any) => ({
id: item.id || item.calculationMajorId, // 根据你实际的ID字段调整
indexs: item.indexs
})).filter((item: any) => item.id); // 过滤掉空行
// 这里调用你的后端接口
// 模拟调用
console.log('提交保存的数据:', sortData);
/*
axiosInstance({
url: ApiConstant.Volunteer.saveOrder, // 替换为你的保存排序接口
method: 'post',
data: sortData
}).then(res => {
if(res.data.success){
ElMessage.success('志愿顺序保存成功');
state.visible.showOrderSaveBtn = false; // 隐藏按钮
getVolunteerDetail(); // 重新获取最新数据
}
});
*/
// 临时模拟成功
ElMessage.success('顺序已保存 (演示)');
state.visible.showOrderSaveBtn = false;
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -1868,4 +1969,16 @@ function returnVolunteerList(){
font-weight: 600; font-weight: 600;
border-bottom: 1px solid #eeeeee; border-bottom: 1px solid #eeeeee;
} }
/* [新增] 拖拽时的样式 */
:deep(.sortable-ghost) {
opacity: 0.8;
background: #ecf5ff !important;
}
:deep(.el-table__row) {
cursor: grab; // 手型光标
}
:deep(.el-table__row:active) {
cursor: grabbing; // 抓取时的光标
}
</style> </style>