init
This commit is contained in:
222
miniprogram/pages/goods/comments/create/index.js
Normal file
222
miniprogram/pages/goods/comments/create/index.js
Normal file
@@ -0,0 +1,222 @@
|
||||
import { createComment } from '../../../../services/comments/createComment';
|
||||
import Toast from 'tdesign-miniprogram/toast/index';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
serviceRateValue: 5,
|
||||
goodRateValue: 5,
|
||||
conveyRateValue: 5,
|
||||
isAnonymous: false,
|
||||
uploadFiles: [],
|
||||
images: [],
|
||||
gridConfig: {
|
||||
width: 218,
|
||||
height: 218,
|
||||
column: 3,
|
||||
},
|
||||
isAllowedSubmit: false,
|
||||
submitting: false,
|
||||
imgUrl: '',
|
||||
title: '',
|
||||
goodsDetail: '',
|
||||
orderNo: '',
|
||||
goodsId: '',
|
||||
maxImages: 9,
|
||||
imageProps: {
|
||||
mode: 'aspectFit',
|
||||
},
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
console.log('评价页面加载参数:', options);
|
||||
this.setData({
|
||||
imgUrl: options.imgUrl ? decodeURIComponent(options.imgUrl) : '',
|
||||
title: options.title ? decodeURIComponent(options.title) : '',
|
||||
goodsDetail: options.specs ? decodeURIComponent(options.specs) : '',
|
||||
orderNo: options.orderNo || '',
|
||||
goodsId: options.goodsId || '',
|
||||
});
|
||||
this.updateButtonStatus();
|
||||
},
|
||||
|
||||
onRateChange(e) {
|
||||
const { value } = e?.detail;
|
||||
const item = e?.currentTarget?.dataset?.item;
|
||||
this.setData({ [item]: value }, () => {
|
||||
this.updateButtonStatus();
|
||||
});
|
||||
},
|
||||
|
||||
onAnonymousChange(e) {
|
||||
const status = !!e?.detail?.checked;
|
||||
this.setData({ isAnonymous: status });
|
||||
},
|
||||
|
||||
|
||||
|
||||
handleSuccess(e) {
|
||||
// 兼容原有的上传组件
|
||||
const { files } = e.detail;
|
||||
const images = files.map(file => file.url);
|
||||
this.setData({
|
||||
uploadFiles: files,
|
||||
images
|
||||
});
|
||||
},
|
||||
|
||||
handleRemove(e) {
|
||||
const { index } = e.detail;
|
||||
const { uploadFiles, images } = this.data;
|
||||
uploadFiles.splice(index, 1);
|
||||
images.splice(index, 1);
|
||||
this.setData({
|
||||
uploadFiles,
|
||||
images
|
||||
});
|
||||
},
|
||||
|
||||
// 上传图片到服务器
|
||||
async uploadImages(images) {
|
||||
if (!images || images.length === 0) return [];
|
||||
|
||||
const uploadPromises = images.map(imagePath => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const uploadUrl = `${getApp().globalData.config.apiBaseUrl}/upload/image`;
|
||||
const token = wx.getStorageSync('token');
|
||||
console.log('上传URL:', uploadUrl);
|
||||
console.log('Token:', token);
|
||||
|
||||
wx.uploadFile({
|
||||
url: uploadUrl,
|
||||
filePath: imagePath,
|
||||
name: 'file',
|
||||
header: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
success: (res) => {
|
||||
try {
|
||||
const data = JSON.parse(res.data);
|
||||
if (data.code === 200) {
|
||||
resolve(data.data.url);
|
||||
} else {
|
||||
reject(new Error(data.message || '上传失败'));
|
||||
}
|
||||
} catch (e) {
|
||||
reject(new Error('解析上传结果失败'));
|
||||
}
|
||||
},
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(uploadPromises);
|
||||
},
|
||||
|
||||
onTextAreaChange(e) {
|
||||
const value = e?.detail?.value;
|
||||
this.textAreaValue = value;
|
||||
this.updateButtonStatus();
|
||||
},
|
||||
|
||||
updateButtonStatus() {
|
||||
const { serviceRateValue, goodRateValue, conveyRateValue, submitting } = this.data;
|
||||
const { textAreaValue } = this;
|
||||
const temp = serviceRateValue && goodRateValue && conveyRateValue && textAreaValue && !submitting;
|
||||
this.setData({ isAllowedSubmit: temp });
|
||||
},
|
||||
|
||||
async onSubmitBtnClick() {
|
||||
const {
|
||||
isAllowedSubmit,
|
||||
submitting,
|
||||
serviceRateValue,
|
||||
goodRateValue,
|
||||
conveyRateValue,
|
||||
isAnonymous,
|
||||
images,
|
||||
orderNo,
|
||||
goodsId
|
||||
} = this.data;
|
||||
|
||||
if (!isAllowedSubmit || submitting) return;
|
||||
|
||||
const content = this.textAreaValue;
|
||||
if (!content || !content.trim()) {
|
||||
Toast({
|
||||
context: this,
|
||||
selector: '#t-toast',
|
||||
message: '请输入评价内容',
|
||||
icon: 'error-circle',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.setData({ submitting: true });
|
||||
this.updateButtonStatus();
|
||||
|
||||
try {
|
||||
// 上传图片
|
||||
let uploadedImages = [];
|
||||
if (images.length > 0) {
|
||||
Toast({
|
||||
context: this,
|
||||
selector: '#t-toast',
|
||||
message: '正在上传图片...',
|
||||
icon: 'loading',
|
||||
});
|
||||
uploadedImages = await this.uploadImages(images);
|
||||
}
|
||||
|
||||
// 计算综合评分(取三个评分的平均值)
|
||||
const averageRating = Math.round((serviceRateValue + goodRateValue + conveyRateValue) / 3);
|
||||
|
||||
// 提交评论
|
||||
const commentData = {
|
||||
orderNo: orderNo,
|
||||
productId: goodsId,
|
||||
rating: averageRating,
|
||||
content: content.trim(),
|
||||
images: uploadedImages,
|
||||
isAnonymous: isAnonymous
|
||||
};
|
||||
|
||||
console.log('提交评论数据:', commentData);
|
||||
|
||||
await createComment(commentData);
|
||||
|
||||
Toast({
|
||||
context: this,
|
||||
selector: '#t-toast',
|
||||
message: '评价提交成功',
|
||||
icon: 'check-circle',
|
||||
});
|
||||
|
||||
// 设置上一页刷新标志
|
||||
const pages = getCurrentPages();
|
||||
const prevPage = pages[pages.length - 2]; // 上一页(订单详情页)
|
||||
if (prevPage) {
|
||||
prevPage.setData({ backRefresh: true });
|
||||
}
|
||||
|
||||
// 延迟返回上一页
|
||||
setTimeout(() => {
|
||||
wx.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
}, 1500);
|
||||
|
||||
} catch (error) {
|
||||
console.error('提交评价失败:', error);
|
||||
Toast({
|
||||
context: this,
|
||||
selector: '#t-toast',
|
||||
message: error.message || '提交失败,请重试',
|
||||
icon: 'error-circle',
|
||||
});
|
||||
} finally {
|
||||
this.setData({ submitting: false });
|
||||
this.updateButtonStatus();
|
||||
}
|
||||
},
|
||||
});
|
||||
13
miniprogram/pages/goods/comments/create/index.json
Normal file
13
miniprogram/pages/goods/comments/create/index.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"navigationBarTitleText": "评价商品",
|
||||
"usingComponents": {
|
||||
"t-image": "/components/webp-image/index",
|
||||
"t-rate": "tdesign-miniprogram/rate/rate",
|
||||
"t-textarea": "tdesign-miniprogram/textarea/textarea",
|
||||
"t-checkbox": "tdesign-miniprogram/checkbox/checkbox",
|
||||
"t-button": "tdesign-miniprogram/button/button",
|
||||
"t-upload": "tdesign-miniprogram/upload/upload",
|
||||
"t-icon": "tdesign-miniprogram/icon/icon",
|
||||
"t-toast": "tdesign-miniprogram/toast/toast"
|
||||
}
|
||||
}
|
||||
93
miniprogram/pages/goods/comments/create/index.wxml
Normal file
93
miniprogram/pages/goods/comments/create/index.wxml
Normal file
@@ -0,0 +1,93 @@
|
||||
<view class="page-container">
|
||||
<view class="comment-card">
|
||||
<view class="goods-info-container">
|
||||
<view class="goods-image-container">
|
||||
<t-image t-class="goods-image" src="{{imgUrl}}" />
|
||||
</view>
|
||||
<view class="goods-title-container">
|
||||
<view class="goods-title">{{title}}</view>
|
||||
<view class="goods-detail">{{goodsDetail}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="rate-container">
|
||||
<text class="rate-title">商品评价</text>
|
||||
<view class="rate">
|
||||
<t-rate
|
||||
value="{{goodRateValue}}"
|
||||
bind:change="onRateChange"
|
||||
size="26"
|
||||
gap="6"
|
||||
color="{{['#ffc51c', '#ddd']}}"
|
||||
data-item="goodRateValue"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="textarea-container">
|
||||
<t-textarea
|
||||
t-class="textarea"
|
||||
maxlength="{{500}}"
|
||||
indicator
|
||||
placeholder="对商品满意吗?评论一下"
|
||||
bind:change="onTextAreaChange"
|
||||
/>
|
||||
</view>
|
||||
<view class="upload-container">
|
||||
<t-upload
|
||||
media-type="{{['image']}}"
|
||||
files="{{uploadFiles}}"
|
||||
bind:remove="handleRemove"
|
||||
bind:success="handleSuccess"
|
||||
gridConfig="{{gridConfig}}"
|
||||
imageProps="{{imageProps}}"
|
||||
max="{{maxImages}}"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="anonymous-box">
|
||||
<t-checkbox bind:change="onAnonymousChange" checked="{{isAnonymous}}" color="#FA4126" />
|
||||
<view class="name">匿名评价</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="comment-card convey-card">
|
||||
<view class="convey-comment-title">物流服务评价</view>
|
||||
<view class="rate-container">
|
||||
<text class="rate-title">物流评价</text>
|
||||
<view class="rate">
|
||||
<t-rate
|
||||
value="{{conveyRateValue}}"
|
||||
bind:change="onRateChange"
|
||||
variant="filled"
|
||||
size="26"
|
||||
gap="6"
|
||||
color="{{['#ffc51c', '#ddd']}}"
|
||||
data-item="conveyRateValue"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="rate-container">
|
||||
<text class="rate-title">服务评价</text>
|
||||
<view class="rate">
|
||||
<t-rate
|
||||
value="{{serviceRateValue}}"
|
||||
bind:change="onRateChange"
|
||||
size="26"
|
||||
gap="6"
|
||||
color="{{['#ffc51c', '#ddd']}}"
|
||||
data-item="serviceRateValue"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="submit-button-container">
|
||||
<t-button
|
||||
content="{{submitting ? '提交中...' : '提交'}}"
|
||||
block
|
||||
shape="round"
|
||||
loading="{{submitting}}"
|
||||
disabled="{{!isAllowedSubmit || submitting}}"
|
||||
t-class="submit-button{{isAllowedSubmit && !submitting ? '' : '-disabled'}}"
|
||||
bind:tap="onSubmitBtnClick"
|
||||
/>
|
||||
</view>
|
||||
<t-toast id="t-toast" />
|
||||
168
miniprogram/pages/goods/comments/create/index.wxss
Normal file
168
miniprogram/pages/goods/comments/create/index.wxss
Normal file
@@ -0,0 +1,168 @@
|
||||
page {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.page-container .comment-card {
|
||||
padding: 24rpx 32rpx 28rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.comment-card .goods-info-container .goods-image {
|
||||
width: 112rpx;
|
||||
height: 112rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.comment-card .goods-info-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.comment-card .goods-info-container .goods-title-container {
|
||||
padding-left: 24rpx;
|
||||
}
|
||||
|
||||
.comment-card .goods-info-container .goods-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.comment-card .goods-info-container .goods-detail {
|
||||
font-size: 24rpx;
|
||||
font-weight: normal;
|
||||
color: #999999;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.comment-card .rate-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 22rpx;
|
||||
}
|
||||
|
||||
.comment-card .rate-container .rate-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.comment-card .textarea-container {
|
||||
margin-top: 22rpx;
|
||||
}
|
||||
|
||||
.comment-card .textarea-container .textarea {
|
||||
height: 294rpx;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 16rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.page-container .t-checkbox__bordered {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-container .anonymous-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 52rpx;
|
||||
}
|
||||
|
||||
.page-container .anonymous-box .name {
|
||||
font-size: 28rpx;
|
||||
font-weight: normal;
|
||||
color: #999999;
|
||||
padding-left: 28rpx;
|
||||
}
|
||||
|
||||
.page-container .t-checkbox {
|
||||
padding: 0rpx !important;
|
||||
}
|
||||
|
||||
.page-container .t-checkbox__content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.comment-card .convey-comment-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.convey-card {
|
||||
background-color: #ffffff;
|
||||
margin-top: 24rpx;
|
||||
padding: 32rpx;
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);
|
||||
}
|
||||
|
||||
.convey-card .rate-container .rate-title {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.page-container .t-checkbox__icon-left {
|
||||
margin-right: 0rpx !important;
|
||||
}
|
||||
|
||||
.submit-button-container {
|
||||
padding: 12rpx 32rpx;
|
||||
display: flex;
|
||||
width: 100vw;
|
||||
box-sizing: border-box;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx);
|
||||
background-color: #ffffff;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.submit-button-container .submit-button {
|
||||
--td-button-default-color: #fff;
|
||||
--td-button-default-bg-color: #fa4126;
|
||||
--td-button-default-border-color: #fa4126;
|
||||
--td-button-default-active-bg-color: #fa42269c;
|
||||
}
|
||||
|
||||
.submit-button-container .submit-button-disabled {
|
||||
--td-button-default-color: #fff;
|
||||
--td-button-default-bg-color: #ccc;
|
||||
--td-button-default-border-color: #ccc;
|
||||
--td-button-default-active-bg-color: rgba(204, 204, 204, 0.789);
|
||||
}
|
||||
|
||||
.page-container .upload-container {
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.page-container .t-upload__wrapper {
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.page-container .submmit-bar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 12;
|
||||
padding: 12rpx 32rpx;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
background-color: #fff;
|
||||
height: 112rpx;
|
||||
}
|
||||
|
||||
.page-container .submmit-bar-button {
|
||||
border-radius: 48rpx !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.page-container .t-upload__close-btn {
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
border-bottom-left-radius: 8rpx;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
|
||||
.upload-container .upload-addcontent-slot {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
Reference in New Issue
Block a user