mrr.sj.front/pages/evaluate/comment.vue

616 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<!-- 顶部导航栏 -->
<custom-navbar title="发布评价" :show-back="true" title-color="#333333" BackText="取消"></custom-navbar>
<!-- <view class="header">
<text class="cancel" @click="cancel">取消</text>
<text class="title">发布评价</text>
<text class="placeholder"></text>
</view> -->
<!-- 打星区域 -->
<view class="rating-section">
<view class="rating-item" v-for="(item, index) in ratings" :key="index">
<view class="rating-item-left">
<text class="rating-label">{{ item.label }}</text>
<view class="stars">
<image v-for="n in 5" :key="n" :src="getStarSrc(index, n)" class="star-img"
:class="{ 'star-animate': activeIndex === index }" @click="rate(index, $event, n)" />
</view>
</view>
<text class="star-text" :class="{ 'text-animate': item.value > 0 }">
{{ item.value > 0 ? item.text : "" }}
</text>
</view>
</view>
<!-- 猜你想说 -->
<view class="guess-section">
<view class="guess-tags">
<view class="guess-title">猜你想说:</view>
<view class="guess-tag" v-for="(tag, index) in guessTags" :key="index" @tap.stop="insertTag(tag.text)">
<image class="tag-icon" :src="tag.icon" />
<text class="tag-text">{{ tag.text }}</text>
</view>
</view>
</view>
<!-- 评论输入 -->
<view class="comment-section">
<highlight-textarea ref="commentInput" placeholder="请描述您对此服务的评价......" type="textarea" @blur="blur" v-model="formData.describe"
:highlightKey="highlightKey">
</highlight-textarea>
<!-- <textarea
class="comment-input"
maxlength="1000"
placeholder="请描述您对此服务的评价......"
v-model="formData.describe"
></textarea> -->
<!-- 上传与匿名 -->
<view class="comment-footer">
<!-- 上传图片 -->
<label class="upload-label">
<input type="file" @change="uploadImage" multiple style="display: none" />
<!-- <image class="upload-icon" src="/static/images/上传图片.png" /> -->
<ali-oss-uploader2 v-model="formData.images" :max-count="9" :max-size="5" :width="'654rpx'"
:user-id="formData.evaluator_id" button-text="上传图片" tips="最多上传9张图片每张不超过5MB"
@success="onUploadSuccess" @error="onUploadError" @delete="onFileDelete"
@ckeckisShowPer="ckeckisShowPer" @ckecknowQer="ckecknowQer">
</ali-oss-uploader2>
</label>
<!-- 匿名评价 -->
<view class="anonymous-wrapper">
<radio class="small-radio" :checked="formData.anonymity == 1"
:color="formData.anonymity == 1 ? '#e10011' : '#ccc'"
@click="formData.anonymity = formData.anonymity == 1 ? 2 : 1" />
<text class="anonymous-text">匿名评价</text>
<text class="tips">隐藏你的头像和名称</text>
</view>
</view>
</view>
<!-- 发布按钮 -->
<view class="submitPage">
<button class="submit-button" @click="submit">发布</button>
</view>
<!-- 获取权限提示匡内容 -->
<view class="permission" :class="{ transform: isShowPer && nowQer === 'xc' }">
<view class="per-tit">美融融plus 对储存空间/照片权限申请说明</view>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像、发布商品等场景中读取相册和文件内容。</view>
</view>
<view class="permission" :class="{ transform: isShowPer && nowQer === 'xj' }">
<view class="per-tit">美融融plus 对相机拍摄权限申请说明</view>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像、发布商品等场景中所需内容。</view>
</view>
</view>
</template>
<script>
import highlightTextarea from "@/components/highlight-textarea/highlight-textarea.vue";
import AliOssUploader2 from "./components/ali-oss-uploader-2.vue";
import request from "../../utils/request";
export default {
components: {
AliOssUploader2,
highlightTextarea
},
data() {
return {
highlightKey: ['团队', '组织'], //违禁词列表
ratings: [{
label: "服务过程",
value: 0,
text: ""
},
{
label: "服务态度",
value: 0,
text: ""
},
{
label: "服务技术",
value: 0,
text: ""
},
{
label: "服务效果",
value: 0,
text: ""
},
],
// 猜你想说标签数据
guessTags: [
{ icon: "https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/3b272e9b-e75b-4093-b3c0-0b3bc790a829.png", text: "服务态度好" },
{ icon: "https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/3b272e9b-e75b-4093-b3c0-0b3bc790a829.png", text: "技术高超" },
{ icon: "https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/3b272e9b-e75b-4093-b3c0-0b3bc790a829.png", text: "卫生安全" },
{ icon: "https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/3b272e9b-e75b-4093-b3c0-0b3bc790a829.png", text: "预约简单" },
{ icon: "https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/3b272e9b-e75b-4093-b3c0-0b3bc790a829.png", text: "操作规范" },
{ icon: "https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/3b272e9b-e75b-4093-b3c0-0b3bc790a829.png", text: "卫生安全" },
{ icon: "https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/3b272e9b-e75b-4093-b3c0-0b3bc790a829.png", text: "卫生安全" }
],
formData: {
images: [], //图片逗号分隔(没有传空字符)
anonymity: 2, //1匿名 2不匿名
evaluator_id: null, //评价人id
order_id: null, //订单id
evaluator_type: 3, //评价人类型 1手艺人 2商家 3用户
order_type: 1, //1:order表用户订单 2:sjorder表商家订单 3:work_hour_order表工时订单 4:work_seat_order表工位订单
describe: "", //评论描述
},
order_kind:1,//是否到店1是到家2是到店
isShowPer: false,
nowQer: "xc",
commentText: "",
anonymous: false,
uploadedImages: [],
activeIndex: null, // 控制当前动画星星组
userInfo: {},
};
},
onLoad(options) {
if (options.id) {
this.formData.order_id = Number(options.id);
}
if (options.evaluator_type) {
this.formData.evaluator_type = Number(options.evaluator_type);
}
if (options.order_type) {
this.formData.order_type = Number(options.order_type);
}
if(options.order_kind==2){
this.order_kind = options.order_kind
this.ratings.push({
label: "门店环境",
value: 0,
text: ""
})
}
this.getUserInfo();
},
methods: {
getUserInfo() {
request.post("/user/getuser", {
type: 1
}).then((result) => {
this.userInfo = result.data;
this.formData.evaluator_id = this.userInfo.id;
});
},
// 插入标签到评论框
insertTag(tagText) {
console.log('点击标签:', tagText);
// 获取当前值
let currentValue = this.formData.describe || '';
let newValue = currentValue ? currentValue + ' ' + tagText : tagText;
// 调用组件的方法
if (this.$refs.commentInput && this.$refs.commentInput.setValue) {
this.$refs.commentInput.setValue(newValue);
}
// 更新父组件的数据
this.formData.describe = newValue;
console.log('当前评论内容:', newValue);
},
ckecknowQer(value) {
this.nowQer = value;
},
ckeckisShowPer(value) {
console.log("ckeckisShowPer==========", value);
this.isShowPer = value;
},
onUploadSuccess(file) {
console.log("添加的图片", this.formData.photo);
},
onUploadError(error) {
console.error("上传失败:", error);
uni.showToast({
title: "上传失败",
icon: "none",
});
},
onFileDelete(file, index) {
console.log("删除文件:", this.formData.photo, index);
},
getStarSrc(index, n) {
const val = this.ratings[index].value;
if (val >= n) return "/static/images/evaluate/star_red2.png";
else if (val >= n - 0.5) return "/static/images/evaluate/star.png";
else return "/static/images/evaluate/star_ash.png";
},
rate(index, e) {
const query = uni.createSelectorQuery().in(this);
query
.selectAll(".stars")
.boundingClientRect((rects) => {
const rect = rects[index];
if (!rect) return;
const x = e.detail.x;
const offsetX = x - rect.left;
const totalWidth = rect.width;
const starWidth = totalWidth / 5;
let rawVal = offsetX / starWidth;
let val = Math.floor(rawVal) + (rawVal % 1 > 0.5 ? 1 : 0.5);
if (val > 5) val = 5;
if (val < 1) val = 1;
this.ratings[index].value = val;
this.ratings[index].text = this.getStarText(val);
// 触发星星动画
this.activeIndex = index;
setTimeout(() => (this.activeIndex = null), 400);
})
.exec();
},
getStarText(value) {
if (value >= 5) return "超预期";
else if (value >= 4) return "还可以";
else if (value >= 3) return "一般";
else if (value >= 1.5) return "较差";
else return "很糟糕";
},
uploadImage(event) {
const files = event.target.files;
if (files.length) {
for (let i = 0; i < files.length; i++) {
this.uploadedImages.push(files[i]);
}
}
console.log("Uploaded images:", this.uploadedImages);
},
cancel() {
console.log("Cancel clicked");
},
async blur(){ // 这个方法不注释会导致点击猜你想说tag时就出现违禁词警告
// 判断违禁词
// let bannedWords = await request.post("/user/orderEvaluate/bannedWords", {
// describe: this.formData.describe
// }).then((res) => {
// if (res.code == 500) {
// this.highlightKey = res.data
// return true
// }
// })
// if (bannedWords) {
// uni.showToast({
// title: `包含违禁词不可发布`,
// icon: "none",
// });
// return;
// }
},
async submit() {
// 判断所有value是否都大于0
let allValuesGreaterThanZero = this.ratings.every(
(item) => item.value > 0
);
if (!allValuesGreaterThanZero) {
uni.showToast({
title: `请选择评价`,
icon: "none",
});
return;
}
// 判断违禁词
let bannedWords = await request.post("/user/orderEvaluate/bannedWords", {
describe: this.formData.describe
}).then((res) => {
if (res.code == 500) {
this.highlightKey = res.data
return true
}
})
if (bannedWords) {
uni.showToast({
title: `包含违禁词不可发布`,
icon: "none",
});
return;
}
let obj = {
...this.formData
};
obj.process = this.ratings[0].value;
obj.attitude = this.ratings[1].value;
obj.technology = this.ratings[2].value;
obj.effect = this.ratings[3].value;
if(this.order_kind==2){
obj.environment = this.ratings[4].value;
}
obj.images = obj.images.join(",");
// obj.environment = this.ratings[4].value
request
.post("/user/orderEvaluate/add", obj)
.then((result) => {
console.log("--", result);
if (result.code == 200) {
// 修改上一页页面信息
const pages = getCurrentPages();
const prevPage = pages[pages.length - 2];
if (prevPage) {
if (prevPage.$vm && typeof prevPage.$vm.getOrderDetail === "function") {
prevPage.$vm.getOrderDetail(); // 存在则调用
}
if (prevPage.$vm && typeof prevPage.$vm.loadOrders === "function") {
prevPage.$vm.loadOrders(); // 存在则调用
}
uni.navigateBack();
}
} else {
uni.showToast({
title: `提交失败`,
icon: "none",
});
}
}).catch((err) => {
console.log(err);
uni.showToast({
title: `提交失败`,
icon: "none",
});
});
console.log(obj);
},
},
};
</script>
<style scoped lang="less">
.container {
background-color: #f8f8f8;
min-height: 100vh;
padding-bottom: 40rpx;
}
/* 顶部导航栏 */
.header {
display: flex;
align-items: center;
justify-content: space-between;
background-color: #fff;
padding: 24rpx 32rpx;
border-bottom: 1rpx solid #f0f0f0;
position: sticky;
top: 0;
z-index: 10;
}
.cancel {
color: #666;
font-size: 30rpx;
}
.placeholder {
width: 60rpx;
}
.title {
font-size: 34rpx;
font-weight: 600;
color: #000;
text-align: center;
flex: 1;
}
/* 打星区域 */
.rating-section {
background-color: #fff;
// padding: 40rpx 30rpx 1rpx 40rpx;
padding: 30rpx 30rpx 1rpx 20rpx;
margin: 20rpx;
border-radius: 20rpx;
}
.rating-item {
display: flex;
align-items: center;
margin-bottom: 52rpx;
justify-content: space-between;
}
.rating-item-left{
display: flex;
align-items: center;
gap: 22rpx;
}
.rating-label {
font-size: 28rpx;
color: #333;
word-break: keep-all;
}
.stars {
display: flex;
gap: 45rpx;
flex-shrink: 0;
}
/* 星星图片基础样式 */
.star-img {
width: 48rpx;
height: 48rpx;
transition: transform 0.2s ease, opacity 0.2s ease;
}
/* 星星点击动画 */
.star-animate {
transform: scale(1.2);
opacity: 0.9;
}
/* 星星描述文字 */
.star-text {
width: 100rpx;
font-size: 26rpx;
text-align: right;
color: #a7a7a7;
opacity: 0;
transform: scale(0.3);
transition: opacity 0.3s ease, transform 0.3s ease;
}
/* 字体动画 */
.text-animate {
opacity: 1;
transform: scale(1);
}
/* 猜你想说 */
.guess-section {
padding: 8rpx 0rpx;
margin: 20rpx;
}
.guess-title {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 30rpx;
color: #000000;
line-height: 42rpx;
text-align: left;
font-style: normal;
flex-shrink: 0;
margin: 10rpx 10rpx 0rpx 5rpx ;
}
.guess-tags {
display: flex;
flex-wrap: wrap;
gap: 11rpx;
}
.guess-tag {
display: flex;
align-items: center;
background-color: #f1f1f1f1;
border-radius: 10rpx;
padding: 12rpx 14rpx;
gap: 12rpx;
margin: 3rpx 0;
}
.tag-icon {
width: 26rpx;
height: 26rpx;
}
.tag-text {
font-size: 26rpx;
color: #666;
}
/* 评论区 */
.comment-section {
background-color: #fff;
padding: 24rpx 32rpx;
margin: 20rpx;
border-radius: 12rpx;
position: relative;
}
.comment-input {
width: 100%;
height: 390rpx;
}
/* 评论区底部功能 */
.comment-footer {
display: flex;
flex-direction: column;
gap: 5rpx;
}
/* 上传图片按钮 */
.upload-label {
display: inline-block;
}
.upload-icon {
width: 140rpx;
height: 140rpx;
}
/* 匿名评价 */
.anonymous-wrapper {
display: flex;
align-items: center;
gap: 4rpx;
}
.anonymous-text {
font-size: 26rpx;
color: #666;
font-weight: bold;
}
.tips {
font-weight: 400;
font-size: 20rpx;
color: #C3C3C3;
text-align: left;
font-style: normal;
}
/* 发布按钮 */
.submitPage{
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 27rpx 0;
background-color: #fff;
.submit-button {
width: 670rpx;
margin: 0 40rpx;
display: block;
background-color: #e10011;
color: #fff;
border: none;
border-radius: 50rpx;
font-size: 32rpx;
font-weight: bold;
}
}
.small-radio {
border: none;
transform: scale(0.7);
}
/* #ifdef APP-PLUS */
.permission.transform {
top: calc(var(--status-bar-height) + 88rpx + 30rpx);
opacity: 1;
visibility: visible;
}
/* #endif */
</style>