Merge branch 'master' of http://g.jimilicai.com:8000/legobackend/lego-manage-web
Showing
3 changed files
with
63 additions
and
6 deletions
| ... | @@ -10,6 +10,7 @@ | ... | @@ -10,6 +10,7 @@ |
| 10 | "preview": "vite preview" | 10 | "preview": "vite preview" |
| 11 | }, | 11 | }, |
| 12 | "dependencies": { | 12 | "dependencies": { |
| 13 | "sortablejs": "^1.15.6", | ||
| 13 | "@element-plus/icons-vue": "2.0.10", | 14 | "@element-plus/icons-vue": "2.0.10", |
| 14 | "@vueup/vue-quill": "1.2.0", | 15 | "@vueup/vue-quill": "1.2.0", |
| 15 | "@vueuse/core": "9.5.0", | 16 | "@vueuse/core": "9.5.0", | ... | ... |
| ... | @@ -5,6 +5,7 @@ | ... | @@ -5,6 +5,7 @@ |
| 5 | :action="uploadFileUrl" | 5 | :action="uploadFileUrl" |
| 6 | :before-upload="handleBeforeUpload" | 6 | :before-upload="handleBeforeUpload" |
| 7 | :file-list="fileList" | 7 | :file-list="fileList" |
| 8 | :limit="limit" | ||
| 8 | :on-error="handleUploadError" | 9 | :on-error="handleUploadError" |
| 9 | :on-exceed="handleExceed" | 10 | :on-exceed="handleExceed" |
| 10 | :on-success="handleUploadSuccess" | 11 | :on-success="handleUploadSuccess" |
| ... | @@ -24,8 +25,20 @@ | ... | @@ -24,8 +25,20 @@ |
| 24 | 的文件 | 25 | 的文件 |
| 25 | </div> | 26 | </div> |
| 26 | <!-- 文件列表 --> | 27 | <!-- 文件列表 --> |
| 27 | <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul"> | 28 | <transition-group |
| 28 | <li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList"> | 29 | class="upload-file-list el-upload-list el-upload-list--text" |
| 30 | name="el-fade-in-linear" | ||
| 31 | tag="ul" | ||
| 32 | ref="fileListWrapper" | ||
| 33 | @update="handleSortUpdate" | ||
| 34 | > | ||
| 35 | <li | ||
| 36 | :key="file.uid" | ||
| 37 | class="el-upload-list__item ele-upload-list__item-content draggable" | ||
| 38 | v-for="(file, index) in fileList" | ||
| 39 | :draggable="true" | ||
| 40 | :title="limit > 1 ? '可拖动文件进行调序' : ''" | ||
| 41 | > | ||
| 29 | <el-link :href="`${file.url}`" :underline="false" target="_blank"> | 42 | <el-link :href="`${file.url}`" :underline="false" target="_blank"> |
| 30 | <span class="el-icon-document"> {{ getFileName(file.name) }} </span> | 43 | <span class="el-icon-document"> {{ getFileName(file.name) }} </span> |
| 31 | </el-link> | 44 | </el-link> |
| ... | @@ -40,9 +53,15 @@ | ... | @@ -40,9 +53,15 @@ |
| 40 | <script setup> | 53 | <script setup> |
| 41 | import { getToken } from "@/utils/auth"; | 54 | import { getToken } from "@/utils/auth"; |
| 42 | import { listByIds, delOss } from "@/api/system/oss"; | 55 | import { listByIds, delOss } from "@/api/system/oss"; |
| 56 | import Sortable from 'sortablejs'; | ||
| 43 | 57 | ||
| 44 | const props = defineProps({ | 58 | const props = defineProps({ |
| 45 | modelValue: [String, Object, Array], | 59 | modelValue: [String, Object, Array], |
| 60 | // 数量限制 | ||
| 61 | limit: { | ||
| 62 | type: Number, | ||
| 63 | default: 5, | ||
| 64 | }, | ||
| 46 | // 大小限制(MB) | 65 | // 大小限制(MB) |
| 47 | fileSize: { | 66 | fileSize: { |
| 48 | type: Number, | 67 | type: Number, |
| ... | @@ -64,13 +83,43 @@ const { proxy } = getCurrentInstance(); | ... | @@ -64,13 +83,43 @@ const { proxy } = getCurrentInstance(); |
| 64 | const emit = defineEmits(); | 83 | const emit = defineEmits(); |
| 65 | const number = ref(0); | 84 | const number = ref(0); |
| 66 | const uploadList = ref([]); | 85 | const uploadList = ref([]); |
| 67 | const baseUrl = import.meta.env.VITE_APP_BASE_API; | 86 | const baseUrl = import.meta.env.VITE_APP_BASE_API || ''; |
| 68 | const uploadFileUrl = ref(baseUrl + "/system/oss/upload"); // 上传文件服务器地址 | 87 | const uploadFileUrl = ref(baseUrl + "/system/oss/upload"); // 上传文件服务器地址 |
| 69 | const headers = ref({ Authorization: "Bearer " + getToken() }); | 88 | const headers = ref({ Authorization: "Bearer " + getToken() }); |
| 70 | const fileList = ref([]); | 89 | const fileList = ref([]); |
| 71 | const showTip = computed( | 90 | const showTip = computed( |
| 72 | () => props.isShowTip && (props.fileType || props.fileSize) | 91 | () => props.isShowTip && (props.fileType || props.fileSize) |
| 73 | ); | 92 | ); |
| 93 | // 初始化拖拽排序 | ||
| 94 | onMounted(() => { | ||
| 95 | const el = proxy.$refs.fileListWrapper.$el; // 确保transition-group添加ref="fileListWrapper" | ||
| 96 | if (el) { | ||
| 97 | new Sortable(el, { | ||
| 98 | animation: 150, // 过渡动画时长 | ||
| 99 | draggable: '.draggable', // 可拖拽的元素 | ||
| 100 | onUpdate: (evt) => { | ||
| 101 | // 拖拽结束时更新列表顺序 | ||
| 102 | const oldIndex = evt.oldIndex; | ||
| 103 | const newIndex = evt.newIndex; | ||
| 104 | |||
| 105 | // 移动元素位置 | ||
| 106 | fileList.value.splice(newIndex, 0, fileList.value.splice(oldIndex, 1)[0]); | ||
| 107 | |||
| 108 | // 触发排序更新事件 | ||
| 109 | handleSortUpdate(); | ||
| 110 | } | ||
| 111 | }); | ||
| 112 | } | ||
| 113 | }); | ||
| 114 | // 排序更新处理 | ||
| 115 | function handleSortUpdate() { | ||
| 116 | // 更新父组件modelValue | ||
| 117 | emit("update:modelValue", listToString(fileList.value)); | ||
| 118 | |||
| 119 | // 输出排序后的列表(可选) | ||
| 120 | console.log('排序后的文件列表:', fileList.value); | ||
| 121 | } | ||
| 122 | |||
| 74 | 123 | ||
| 75 | watch(() => props.modelValue, async val => { | 124 | watch(() => props.modelValue, async val => { |
| 76 | if (val) { | 125 | if (val) { |
| ... | @@ -124,6 +173,10 @@ function handleBeforeUpload(file) { | ... | @@ -124,6 +173,10 @@ function handleBeforeUpload(file) { |
| 124 | return true; | 173 | return true; |
| 125 | } | 174 | } |
| 126 | 175 | ||
| 176 | // 文件个数超出 | ||
| 177 | function handleExceed() { | ||
| 178 | proxy.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`); | ||
| 179 | } | ||
| 127 | 180 | ||
| 128 | // 上传失败 | 181 | // 上传失败 |
| 129 | function handleUploadError(err) { | 182 | function handleUploadError(err) { |
| ... | @@ -206,4 +259,7 @@ function listToString(list, separator) { | ... | @@ -206,4 +259,7 @@ function listToString(list, separator) { |
| 206 | .ele-upload-list__item-content-action .el-link { | 259 | .ele-upload-list__item-content-action .el-link { |
| 207 | margin-right: 10px; | 260 | margin-right: 10px; |
| 208 | } | 261 | } |
| 262 | .draggable { | ||
| 263 | cursor: move; | ||
| 264 | } | ||
| 209 | </style> | 265 | </style> | ... | ... |
| ... | @@ -132,13 +132,13 @@ | ... | @@ -132,13 +132,13 @@ |
| 132 | </template> | 132 | </template> |
| 133 | </el-form-item> | 133 | </el-form-item> |
| 134 | <el-form-item :label="$t('course.dialogCase')" prop="caseOssId" label-width="80"> | 134 | <el-form-item :label="$t('course.dialogCase')" prop="caseOssId" label-width="80"> |
| 135 | <fileUpload v-model="showForm.form.caseOssId" :fileType='["mp4", "avi", "mov", "flv","pdf"]'/> | 135 | <fileUpload v-model="showForm.form.caseOssId" :limit="10" :fileType='["mp4", "avi", "mov", "flv","pdf"]'/> |
| 136 | </el-form-item> | 136 | </el-form-item> |
| 137 | <el-form-item :label="$t('course.dialogTeaching')" label-width="80"> | 137 | <el-form-item :label="$t('course.dialogTeaching')" label-width="80"> |
| 138 | <fileUpload v-model="showForm.form.teachingOssId" :fileType='["pdf","mp4"]'/> | 138 | <fileUpload v-model="showForm.form.teachingOssId" :limit="10" :fileType='["pdf","mp4"]'/> |
| 139 | </el-form-item> | 139 | </el-form-item> |
| 140 | <el-form-item :label="$t('course.dialogPpt')" label-width="80"> | 140 | <el-form-item :label="$t('course.dialogPpt')" label-width="80"> |
| 141 | <fileUpload v-model="showForm.form.pptOssId" :fileType='["pdf","mp4"]'/> | 141 | <fileUpload v-model="showForm.form.pptOssId" :limit="10" :fileType='["pdf","mp4"]'/> |
| 142 | </el-form-item> | 142 | </el-form-item> |
| 143 | <el-form-item :label="$t('course.dialogPhoto')" prop="ossId" label-width="80"> | 143 | <el-form-item :label="$t('course.dialogPhoto')" prop="ossId" label-width="80"> |
| 144 | <imageUpload v-model="showForm.form.ossId" :limit='1' :fileType='["png", "jpg", "jpeg", "ico"]'/> | 144 | <imageUpload v-model="showForm.form.ossId" :limit='1' :fileType='["png", "jpg", "jpeg", "ico"]'/> | ... | ... |
-
Please register or sign in to post a comment