| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- <template>
- <view class="uploadFile_wrap">
- <!-- 上传按钮 -->
- <view class="upload_btn_wrap" @click="handleUpload">
- <view class="upload_btn_content">
- <view class="upload_icon">
- <u-icon name="plus-circle" size="24" color="#fff"></u-icon>
- </view>
- <text class="upload_text">上传文件</text>
- </view>
- </view>
- <!-- 文件列表分类展示 -->
- <view class="fileList_wrap" v-if="!loading && dataList.length > 0">
- <view class="file_item_wrap" v-if="imgList.length > 0">
- <view class="item_title">图片文件:</view>
- <mk-upload
- :imgList="imgList"
- @onDelete="handleDelFile"
- :controlShow="false"
- type="image"
- @onPreviewTake="handlePreviewImage"
- ></mk-upload>
- </view>
- <view class="file_item_wrap" v-if="recordList.length > 0">
- <view class="item_title">录音文件:</view>
- <mk-upload
- :imgList="recordList"
- @onDelete="handleDelFile"
- :controlShow="false"
- type="record"
- @onPreviewTake="handlePreviewRecord"
- ></mk-upload>
- </view>
- <view class="file_item_wrap" v-if="videoList.length > 0">
- <view class="item_title">视频文件:</view>
- <mk-upload
- :imgList="videoList"
- @onDelete="handleDelFile"
- :controlShow="false"
- type="video"
- @onPreviewTake="handlePreviewVideo"
- ></mk-upload>
- </view>
- <view class="file_item_wrap" v-if="otherList.length > 0">
- <view class="item_title">其他文件:</view>
- <mk-upload
- :imgList="otherList"
- @onDelete="handleDelFile"
- :controlShow="false"
- type="file"
- @onPreviewTake="handlePreviewFile"
- ></mk-upload>
- </view>
- </view>
- <!-- 加载状态 -->
- <view v-if="loading" class="loading_wrap">
- <u-loading-icon text="加载中" textSize="18"></u-loading-icon>
- </view>
- <!-- 空状态 -->
- <view v-else-if="dataList.length === 0" class="empty_wrap">
- <u-empty text="暂无文件数据"></u-empty>
- </view>
- <!-- 图片预览 -->
- <u-image
- ref="previewImg"
- :src="previewImageSrc"
- mode="widthFix"
- v-if="previewImageSrc"
- @click="previewImageSrc = ''"
- ></u-image>
- <!-- 文件预览模态框 -->
- <u-modal :show="showFileModal" :title="currentFile.fileName" @confirm="handleFileConfirm">
- <view v-if="currentFile && currentFile.fileUrl" class="currentFile_wrap">
- <audio
- style="text-align: left"
- :src="currentFile.fileUrl"
- :name="'点击播放'"
- controls
- v-if="['wav','mp3','aac','wma'].includes(currentFile.fileSuffix)"
- ></audio>
- <video
- :src="currentFile.fileUrl"
- mode=""
- class="currentFile_image"
- v-else-if="showFileModal"
- show-fullscreen-btn
- ></video>
- </view>
- <view v-else>
- 文件异常
- </view>
- </u-modal>
- <!-- 编辑对话框 -->
- <u-popup v-model="dialogVisible" mode="center" width="500rpx" border-radius="16">
- <view class="dialog_header">{{ dialogTitle }}</view>
- <view class="dialog_body">
- <u-form :model="fileForm" ref="fileFormRef" label-width="100px">
- <u-form-item label="文件名称" prop="fileName">
- <u-input v-model="fileForm.fileName" placeholder="请输入文件名称" />
- </u-form-item>
- <u-form-item label="备注" prop="remark">
- <u-input v-model="fileForm.remark" type="textarea" placeholder="请输入备注信息" />
- </u-form-item>
- </u-form>
- </view>
- <view class="dialog_footer">
- <u-button @click="handleClose">取消</u-button>
- <u-button type="primary" @click="handleEditSubmit">确定</u-button>
- </view>
- </u-popup>
- </view>
- </template>
- <script>
- import mkUpload from "@/components/mk-upload/mk-upload.vue"
- import upload from '@/mixins/upload';
- export default {
- name: 'UploadFile',
- mixins : [upload],
- components: {
- mkUpload
- },
- props: {
- clueId: { type: [String, Number], required: true },
- sourceId: { type: [String, Number], default: '' },
- type: { type: String, required: true },
- orderFileType: { type: String, default: '' },
- isDuplicate: { type: String, default: '2' }
- },
- computed: {
- imgList() {
- return this.dataList.filter(v => ['png','gif','bmp','jpg','jpeg','webp'].includes((v.fileSuffix || '').toLowerCase()));
- },
- recordList() {
- return this.dataList.filter(v => ['wav','mp3','aac','wma'].includes((v.fileSuffix || '').toLowerCase()));
- },
- videoList() {
- return this.dataList.filter(v => ['avi','mkv','mov','wmv','mp4'].includes((v.fileSuffix || '').toLowerCase()));
- },
- otherList() {
- const list = this.imgList.concat(this.recordList).concat(this.videoList);
- return this.dataList.filter(v => !list.some(j => j.id === v.id));
- }
- },
- data() {
- return {
- loading: false,
- dataList: [],
- previewImageSrc: '',
- showFileModal: false,
- currentFile: {},
- // 编辑对话框相关
- dialogVisible: false,
- dialogTitle: '编辑文件',
- fileForm: {
- id: null,
- fileName: '',
- remark: ''
- }
- }
- },
- methods: {
- async handleUploadSuccess(){
- await uni.$u.api.saveClueFile({
- clueId : this.clueId,
- list : this.uploadList,
- sourceId: this.sourceId,
- type : this.type,
- orderFileType : this.orderFileType
- });
- uni.$u.toast("上传成功");
- // 清空
- this.uploadList = [];
- this.getList();
- },
- // 获取文件列表
- async getList() {
- // 检查必要参数是否存在
- if (!this.clueId) {
- return;
- }
- this.loading = true
- try {
- const params = {
- clueId: this.clueId,
- sourceId: this.sourceId,
- type: this.type,
- orderFileType: this.orderFileType,
- isDuplicate: this.isDuplicate,
- pageNum: 1,
- pageSize: 1000 // 设置一个较大的值以获取所有数据
- }
- const response = await uni.$u.api.selectClueFileByDto(params)
- this.dataList = response.rows || []
- } catch (error) {
- uni.$u.toast(`获取列表失败:${error.message}`)
- this.dataList = []
- } finally {
- this.loading = false
- }
- },
- // 删除文件
- async handleDelFile(item) {
- try {
- await uni.$u.api.deleteClueFile([item.id])
- uni.$u.toast('删除成功')
- this.getList()
- } catch (error) {
- uni.$u.toast(`删除失败:${error.message}`)
- }
- },
- // 预览图片
- handlePreviewImage(item) {
- const imgList = this.imgList.map(v => v.fileUrl);
- const currentIndex = imgList.findIndex(url => url === item.fileUrl);
- uni.previewImage({
- current: currentIndex >= 0 ? currentIndex : 0,
- urls: imgList
- });
- },
- // 预览录音
- handlePreviewRecord(item) {
- this.currentFile = item;
- this.showFileModal = true;
- },
- // 预览视频
- handlePreviewVideo(item) {
- this.currentFile = item;
- this.showFileModal = true;
- },
- // 预览其他文件
- handlePreviewFile(item) {
- uni.$u.toast("其他文件不支持预览,可前往网页端查看");
- },
- // 关闭文件预览
- handleFileConfirm() {
- this.showFileModal = false;
- },
- // 编辑文件
- handleEdit(row) {
- this.dialogTitle = '编辑文件'
- this.fileForm = {
- id: row.id,
- fileName: row.fileName,
- remark: row.remark
- }
- this.dialogVisible = true
- },
- // 提交编辑表单
- async handleEditSubmit() {
- try {
- await uni.$u.api.updateClueFile(this.fileForm)
- uni.$u.toast('编辑成功')
- this.dialogVisible = false
- this.getList()
- } catch (error) {
- uni.$u.toast(`编辑失败:${error.message}`)
- }
- },
- // 关闭对话框
- handleClose() {
- this.dialogVisible = false
- this.fileForm = {
- id: null,
- fileName: '',
- remark: ''
- }
- }
- },
- created() {
- this.getList();
- }
- }
- </script>
- <style lang="scss" scoped>
- .uploadFile_wrap {
- padding: 0 20px 20px;
- }
- .upload_btn_wrap {
- margin-top: 10px;
- margin-bottom: 10px;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- border-radius: 12px;
- padding: 16px 20px;
- box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
- transition: all 0.3s ease;
- position: relative;
- overflow: hidden;
- }
- .upload_btn_wrap::before {
- content: '';
- position: absolute;
- top: 0;
- left: -100%;
- width: 100%;
- height: 100%;
- background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
- transition: left 0.5s;
- }
- .upload_btn_wrap:active::before {
- left: 100%;
- }
- .upload_btn_wrap:active {
- transform: scale(0.98);
- box-shadow: 0 2px 8px rgba(102, 126, 234, 0.4);
- }
- .upload_btn_content {
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 8px;
- position: relative;
- z-index: 1;
- }
- .upload_icon {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 32px;
- height: 32px;
- background: rgba(255, 255, 255, 0.2);
- border-radius: 50%;
- backdrop-filter: blur(10px);
- }
- .upload_text {
- color: #fff;
- font-size: 16px;
- font-weight: 600;
- letter-spacing: 0.5px;
- }
- .fileList_wrap {
- padding: 0;
- color: #666666;
- font-size: 24rpx;
-
- .file_item_wrap {
- margin-bottom: 20px;
-
- .item_title {
- margin-bottom: 10px;
- font-weight: bold;
- font-size: 16px;
- color: #202020;
- }
- }
- }
- .currentFile_wrap {
- .file_audio {
- height: 60px;
- width: 100%;
- }
- .currentFile_image {
- height: 42vh;
- object-fit: contain;
- }
- }
- .loading_wrap,
- .empty_wrap {
- padding: 40px 20px;
- text-align: center;
- }
- .dialog_header {
- padding: 20px;
- font-size: 16px;
- font-weight: bold;
- text-align: center;
- border-bottom: 1px solid #e9ecef;
- }
- .dialog_body {
- padding: 20px;
- }
- .dialog_footer {
- padding: 20px;
- display: flex;
- justify-content: space-around;
- border-top: 1px solid #e9ecef;
- }
- </style>
|