| | |
| | | <template> |
| | | <up-popup |
| | | v-model:show="showPopup" |
| | | mode="bottom" |
| | | @open="handleOpen" |
| | | @close="handleClose" |
| | | close-on-click-overlay |
| | | > |
| | | <up-popup v-model:show="showPopup" mode="bottom" @open="handleOpen" @close="handleClose" close-on-click-overlay> |
| | | <view class="comment-popup"> |
| | | <up-textarea |
| | | v-model="commentContent" |
| | | placeholder="请输入内容" |
| | | count |
| | | :focus="isFocus" |
| | | :cursor-spacing="200" |
| | | |
| | | /> |
| | | <up-textarea v-model="comment.content" placeholder="请输入内容" count :focus="isFocus" :cursor-spacing="200" /> |
| | | |
| | | <view class="comment-btn-view"> |
| | | <view class="comment-btn-icon"> |
| | |
| | | <up-icon name="plus-circle" size="60rpx" color="#999999" /> |
| | | </view> |
| | | <view class="comment-btn"> |
| | | <up-button |
| | | :disabled="!canSend" |
| | | type="error" |
| | | shape="circle" |
| | | text="发送" |
| | | size="mini" |
| | | @click="sendComment" |
| | | /> |
| | | <up-button :disabled="!canSend" type="error" shape="circle" text="发送" size="mini" @click="sendComment" /> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="comment-image-upload" v-if="fileList.length > 0"> |
| | | <up-upload |
| | | :file-list="fileList" |
| | | name="file" |
| | | :auto-upload="false" |
| | | :max-count="9" |
| | | upload-text="上传图片" |
| | | width="130rpx" |
| | | height="130rpx" |
| | | :cursor-spacing="200" |
| | | multiple |
| | | @delete="handleDelete" |
| | | /> |
| | | <up-upload :file-list="fileList" name="file" :auto-upload="false" :max-count="9" upload-text="上传图片" |
| | | width="130rpx" height="130rpx" :cursor-spacing="200" multiple @delete="handleDelete" /> |
| | | </view> |
| | | </view> |
| | | </up-popup> |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref, watch, computed } from 'vue'; |
| | | |
| | | interface FileItem { |
| | | url: string; |
| | | status: string; |
| | | } |
| | | import { useGlobal } from '@/composables/useGlobal' |
| | | const { $http, $message, $store } = useGlobal() |
| | | import { CommentDTO, FileItem } from '@/types/index' |
| | | |
| | | const props = defineProps<{ |
| | | modelValue: boolean; // 修改这里 |
| | | modelValue: boolean; |
| | | parentId: string; |
| | | filmId: string; |
| | | }>(); |
| | | |
| | | const emit = defineEmits(['update:modelValue']); // 修改这里 |
| | | const emit = defineEmits(['update:modelValue', 'success']); // 修改这里 |
| | | |
| | | const showPopup = ref(props.modelValue); |
| | | |
| | | const commentContent = ref(''); |
| | | const isFocus = ref(false); |
| | | const focusLock = ref(false); |
| | | const fileList = ref<FileItem[]>([]); |
| | | const pictureList = ref<FileItem[]>([]); |
| | | const comment = ref<CommentDTO>({ |
| | | parentId: props.parentId, |
| | | filmId: props.filmId, |
| | | content: '', |
| | | fileList: [], |
| | | filmPictures:'', |
| | | }) |
| | | |
| | | const uploadUrl = 'https://your-api.com/upload'; // 替换成你的上传接口地址 |
| | | watch(pictureList, (newList) => { |
| | | comment.value.fileList = newList; |
| | | comment.value.filmPictures=JSON.stringify(newList); |
| | | }, { immediate: true, deep: true }); |
| | | |
| | | // 监听外部传入的 modelValue,同步到内部 showPopup |
| | | watch( |
| | |
| | | }); |
| | | |
| | | const canSend = computed(() => { |
| | | return commentContent.value.trim() !== '' || fileList.value.length > 0; |
| | | return comment.value.content.trim() !== '' || comment.value.fileList.length > 0; |
| | | }); |
| | | |
| | | const handleOpen = () => { |
| | |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | isFocus.value = false; |
| | | showPopup.value = false; |
| | | // isFocus.value = false; |
| | | // showPopup.value = false; |
| | | }; |
| | | |
| | | const chooseImage = () => { |
| | | uni.chooseImage({ |
| | | count: 9 - fileList.value.length, |
| | | sizeType: ['original', 'compressed'], |
| | | sourceType: ['album', 'camera'], |
| | | success: (res) => { |
| | | res.tempFilePaths.forEach((filePath) => { |
| | | const fileItem: FileItem = { |
| | | url: filePath, |
| | | status: 'ready', |
| | | }; |
| | | fileList.value.push(fileItem); |
| | | uploadImage(filePath); |
| | | }); |
| | | }, |
| | | fail: (err) => { |
| | | console.error('选择图片失败:', err); |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | const uploadImage = (filePath: string) => { |
| | | uni.uploadFile({ |
| | | url: uploadUrl, |
| | | filePath, |
| | | name: 'file', |
| | | success: (res) => { |
| | | console.log('上传成功:', res); |
| | | // 可解析 res 并更新 fileList 中的 fileItem.url 为服务器返回地址 |
| | | }, |
| | | fail: (err) => { |
| | | console.error('上传失败:', err); |
| | | }, |
| | | uni.chooseImage({ |
| | | count: 9 - fileList.value.length, // 最多可以选择的图片张数,默认9 |
| | | sizeType: ['compressed'], //original 原图,compressed 压缩图,默认二者都有 |
| | | sourceType: ['camera', 'album'], //album 从相册选图,camera 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项 |
| | | success: async function (res: any) { |
| | | let errMsg = res.errMsg; |
| | | if (errMsg === 'chooseImage:ok') { |
| | | // 检查文件大小 |
| | | let oversizedFile = res.tempFiles.find(file => file.size > 1024 * 1024 * 5); |
| | | if (oversizedFile) { |
| | | $message.confirm('图片最多支持5M大小,超出大小限制'); |
| | | return; |
| | | } |
| | | |
| | | // 显示加载提示 |
| | | $message.showLoading(); |
| | | |
| | | // 获取所有文件的 path 数组 |
| | | res.tempFiles.forEach((file) => { |
| | | const fileItem: FileItem = { |
| | | name: file.name || '', |
| | | size:file.size, |
| | | url: file.path, |
| | | status: 'ready', |
| | | }; |
| | | fileList.value.push(fileItem); |
| | | }); |
| | | |
| | | |
| | | |
| | | // 创建上传请求的数组 |
| | | const uploadPromises = fileList.value.map(tmpfile => { |
| | | return $http.upload(tmpfile.url) |
| | | .then(res => { |
| | | let pic = res.data && res.data.length > 0 && res.data[0].url || ''; |
| | | return pic; |
| | | }) |
| | | .catch(err => { |
| | | console.error(err); |
| | | return null; // 上传失败时返回 null |
| | | }); |
| | | }); |
| | | |
| | | // 使用 Promise.all 并发上传 |
| | | try { |
| | | const resImages = await Promise.all(uploadPromises); |
| | | |
| | | console.log("resImages",resImages) |
| | | |
| | | // 检查上传结果 |
| | | const successfulImages = resImages.filter(pic => pic !== null); |
| | | const fileItem: FileItem = { |
| | | name: '', |
| | | size:0, |
| | | url: successfulImages, |
| | | status: 'ready', |
| | | }; |
| | | pictureList.value.push(fileItem); |
| | | console.log('上传成功:', pictureList.value); |
| | | $message.hideLoading(); |
| | | |
| | | if (successfulImages.length !== fileList.value.length) { |
| | | // 部分上传失败 |
| | | $message.showToast('部分文件上传失败,请重新尝试!'); |
| | | } |
| | | } catch (err) { |
| | | console.error(err); |
| | | $message.showToast('文件上传失败,请联系管理员'); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | |
| | | fileList.value.splice(index, 1); |
| | | }; |
| | | |
| | | const sendComment = () => { |
| | | const sendComment = async () => { |
| | | if (!canSend.value) return; |
| | | |
| | | console.log('发送评论:', commentContent.value); |
| | | console.log('附带图片:', fileList.value.map((f) => f.url)); |
| | | console.log("评论添加:", comment.value) |
| | | const { |
| | | code, data |
| | | } = await $http.request('post', '/api/comment/create', { |
| | | data: comment.value |
| | | }) |
| | | if (code == 0) { |
| | | // 保存成功,返回评论? |
| | | console.log("评论新增成功") |
| | | emit('success'); // 告诉父组件刷新列表 |
| | | emit('update:modelValue', false); // 关闭弹窗 |
| | | |
| | | // 提交评论逻辑 |
| | | commentContent.value = ''; |
| | | } else { |
| | | $message.showToast('系统异常,无法获取当前微信是否已经绑定过账号') |
| | | } |
| | | |
| | | fileList.value = []; |
| | | handleClose(); |
| | | // handleClose(); |
| | | }; |
| | | |
| | | |
| | | const submitComment = async () => { |
| | | |
| | | |
| | | }; |
| | | </script> |
| | | |