- <template>
- <view>
- <uv-popup ref="popup" :round="30">
- <view class="comment-publish">
- <!-- 回复目标信息显示 -->
- <view class="reply-target" v-if="replyParams && replyParams.replyToName">
- <view class="reply-info">
- <text class="reply-text">回复 @{{ replyParams.replyToName }}:</text>
- <text class="cancel-reply" @click="cancelReply">×</text>
- </view>
- </view>
-
- <view class="content-input">
- <uv-textarea v-model="form.userValue" :maxlength="200" autoHeight count focus
- :placeholder="replyParams && replyParams.replyToName ? `回复 @${replyParams.replyToName}` : placeholder"></uv-textarea>
- </view>
-
- <view class="images box">
- <uv-upload :fileList="fileList" :maxCount="imageMax" multiple width="150rpx" height="150rpx"
- @delete="deleteImage" @afterRead="afterRead"
- :sizeType="['original', 'compressed']"
- :previewFullImage="true"></uv-upload>
- </view>
-
- <view class="uni-color-btn" @click="submit">
- 发布
- </view>
- </view>
- </uv-popup>
-
- <!-- 邮箱填写弹窗组件 -->
- <email-popup ref="emailPopup" @skip="handleEmailSkip" @confirm="handleEmailConfirm"></email-popup>
- </view>
- </template>
-
- <script>
- import { mapState } from 'vuex'
- import EmailPopup from './emailPopup.vue'
- import { subscribeBeforePublish } from '@/utils/subscribeMessage.js'
-
- export default {
- name: 'CommentPublish',
- components: {
- EmailPopup
- },
- props: {
- // 评论参数
- params: {
- type: Object,
- default: () => ({})
- },
- // 输入框占位符
- placeholder: {
- type: String,
- default: '说点什么吧...'
- }
- },
- computed: {
- ...mapState(['userInfo'])
- },
- data() {
- return {
- form: {
- userValue: ''
- },
- imageMax: 9,
- fileList: [],
- replyParams: null // 回复参数
- }
- },
- methods: {
- // 打开弹窗
- open() {
- this.$refs.popup.open('bottom')
- },
-
- // 关闭弹窗
- close() {
- this.$refs.popup.close()
- },
-
- // 检查邮箱并提交
- async submit() {
- // 检查用户是否填写了邮箱
- if (!this.userInfo.mail) {
- this.$refs.emailPopup.show()
- return
- }
-
- this.doSubmit()
- },
-
- // 处理邮箱跳过事件
- handleEmailSkip() {
- this.doSubmit()
- },
-
- // 处理邮箱确认事件
- handleEmailConfirm(email) {
- this.doSubmit()
- },
-
- // 执行提交评论
- async doSubmit() {
- await subscribeBeforePublish()
-
- let data = {
- ...this.form,
- ...this.params,
- }
-
- // 如果是回复评论,添加回复参数
- if (this.replyParams) {
- data = {
- ...data,
- pid: this.replyParams.pid, // 添加 pid 参数
- replyToId: this.replyParams.replyToId,
- replyToName: this.replyParams.replyToName, // 确保 replyToName 传递给后端
- replyToAvatar: this.replyParams.replyToAvatar
- }
-
- // 在前端也存储 replyToName,确保数据一致性
- console.log('回复参数:', {
- pid: data.pid,
- replyToId: data.replyToId,
- replyToName: data.replyToName,
- replyToAvatar: data.replyToAvatar
- });
- }
-
- if (this.$utils.verificationAll(data, {
- userValue: '说点什么吧',
- type: '缺少type',
- orderId: '缺少orderId',
- })) {
- return
- }
-
- data.userImage = this.fileList.map((item) => item.url).join(",")
-
- this.$api('addComment', data, res => {
- console.log('addComment API 响应:', res);
- if (res.code == 200) {
- this.close()
- this.resetForm()
- uni.showToast({
- title: '发布成功!',
- icon: 'none'
- })
- // 传递回复信息给父组件,用于更新子评论列表
- const successData = {
- isReply: !!data.pid,
- parentId: data.pid,
- replyData: data
- };
- console.log('准备触发success事件,数据:', successData);
- this.$emit('success', successData)
- }
- })
- },
-
- // 重置表单
- resetForm() {
- this.form.userValue = ''
- this.fileList = []
- this.replyParams = null
- },
-
- // 设置回复参数
- setReplyParams(params) {
- this.replyParams = params
- },
-
- // 取消回复
- cancelReply() {
- this.replyParams = null
- },
-
- deleteImage(e) {
- this.fileList.splice(e.index, 1)
- },
-
- afterRead(e) {
- let self = this
- e.file.forEach(file => {
- self.$Oss.ossUpload(file.url).then(url => {
- self.fileList.push({
- url
- })
- })
- })
- },
- }
- }
- </script>
-
- <style scoped lang="scss">
- .comment-publish {
- .reply-target {
- padding: 20rpx;
- background-color: #f5f5f5;
- border-bottom: 1px solid #e5e5e5;
-
- .reply-info {
- display: flex;
- justify-content: space-between;
- align-items: center;
-
- .reply-text {
- color: #666;
- font-size: 28rpx;
- }
-
- .cancel-reply {
- color: #999;
- font-size: 36rpx;
- font-weight: bold;
- padding: 0 10rpx;
- }
- }
- }
-
- .content-input {
- min-height: 400rpx;
- }
-
- .box {
- padding: 0 20rpx;
- }
-
- .images {
- display: flex;
- flex-wrap: wrap;
- padding: 20rpx;
- }
-
- .uni-color-btn {
- background-color: $uni-color-primary;
- color: #fff;
- text-align: center;
- padding: 20rpx;
- margin: 20rpx;
- border-radius: 10rpx;
- font-size: 32rpx;
- }
- }
- </style>
|