<template>
|
<div class="evaluation-container">
|
<!-- 页面头部 -->
|
<div class="evaluation-header">
|
<h1>服务评价</h1>
|
<p>感谢您使用我们的服务,请对本次服务进行评价</p>
|
</div>
|
|
<!-- 车辆信息 -->
|
<div class="vehicle-info" v-if="vehicleNo">
|
<div class="info-item">
|
<span class="label">车牌号:</span>
|
<span class="value">{{ vehicleNo }}</span>
|
</div>
|
</div>
|
|
<!-- 评价表单 -->
|
<div class="evaluation-form">
|
<el-form ref="evaluationForm" :model="evaluationForm" :rules="rules" label-width="80px" size="small">
|
<!-- 客户信息 -->
|
<div class="form-section">
|
<h3>客户信息</h3>
|
<el-form-item label="姓名" prop="customerName">
|
<el-input v-model="evaluationForm.customerName" placeholder="请输入您的姓名" />
|
</el-form-item>
|
<el-form-item label="手机号" prop="customerPhone">
|
<el-input v-model="evaluationForm.customerPhone" placeholder="请输入您的手机号" />
|
</el-form-item>
|
</div>
|
|
<!-- 评价维度 -->
|
<div class="form-section">
|
<h3>服务评价</h3>
|
<div v-for="dimension in dimensions" :key="dimension.dimensionId" class="dimension-item">
|
<!-- 星级评价 - 标题和评分在同一行 -->
|
<div v-if="dimension.dimensionType === 'star'" class="star-rating-inline">
|
<div class="dimension-title-inline">
|
<span>{{ dimension.dimensionName }}</span>
|
<span v-if="dimension.isRequired === '1'" class="required">*</span>
|
</div>
|
<div class="star-rating-content">
|
<el-rate
|
:value="getDimensionScore(dimension.dimensionId)"
|
:max="5"
|
show-text
|
:texts="['很差', '较差', '一般', '满意', '非常满意']"
|
@change="updateDimensionScore(dimension.dimensionId, $event)"
|
size="small"
|
/>
|
</div>
|
</div>
|
|
<!-- 选择评价 -->
|
<div v-else-if="dimension.dimensionType === 'select'">
|
<div class="dimension-title">
|
<span>{{ dimension.dimensionName }}</span>
|
<span v-if="dimension.isRequired === '1'" class="required">*</span>
|
</div>
|
<div class="dimension-desc" v-if="dimension.dimensionDesc">
|
{{ dimension.dimensionDesc }}
|
</div>
|
<div class="select-rating">
|
<el-radio-group :value="getDimensionOption(dimension.dimensionId)" @change="updateDimensionOption(dimension.dimensionId, $event)" size="small">
|
<el-radio v-for="option in getDimensionOptions(dimension)" :key="option.value" :label="option.value">
|
{{ option.label }}
|
</el-radio>
|
</el-radio-group>
|
</div>
|
</div>
|
|
<!-- 文本评价 -->
|
<div v-else-if="dimension.dimensionType === 'text'">
|
<div class="dimension-title">
|
<span>{{ dimension.dimensionName }}</span>
|
<span v-if="dimension.isRequired === '1'" class="required">*</span>
|
</div>
|
<div class="dimension-desc" v-if="dimension.dimensionDesc">
|
{{ dimension.dimensionDesc }}
|
</div>
|
<div class="text-rating">
|
<el-input
|
:value="getDimensionText(dimension.dimensionId)"
|
type="textarea"
|
:rows="2"
|
placeholder="请输入您的意见或建议"
|
@input="updateDimensionText(dimension.dimensionId, $event)"
|
size="small"
|
/>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
<!-- 提交按钮 -->
|
<div class="form-actions">
|
<el-button type="primary" size="large" @click="submitEvaluation" :loading="submitting">
|
提交评价
|
</el-button>
|
</div>
|
</el-form>
|
</div>
|
|
<!-- 结果页面 -->
|
<div v-if="showResult" class="result-page">
|
<div class="result-content">
|
<div class="result-icon">
|
<i class="el-icon-success" style="font-size: 60px; color: #67C23A;"></i>
|
</div>
|
<div class="result-message">
|
{{ resultMessage }}
|
</div>
|
<div class="result-actions">
|
<el-button type="primary" @click="resetForm">再次评价</el-button>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import { getEvaluationDimensions, submitEvaluation, getWechatUserInfo } from "@/api/evaluation";
|
|
export default {
|
name: "Evaluation",
|
data() {
|
return {
|
vehicleNo: '',
|
dimensions: [],
|
evaluationForm: {
|
vehicleNo: '',
|
customerName: '',
|
customerPhone: '',
|
wechatOpenid: '',
|
wechatNickname: '',
|
wechatAvatar: '',
|
wechatPhone: '',
|
evaluationDetails: []
|
},
|
rules: {
|
customerName: [
|
{ required: true, message: '请输入您的姓名', trigger: 'blur' }
|
],
|
customerPhone: [
|
{ required: true, message: '请输入您的手机号', trigger: 'blur' },
|
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
|
]
|
},
|
submitting: false,
|
showResult: false,
|
resultMessage: ''
|
};
|
},
|
created() {
|
this.initPage();
|
},
|
methods: {
|
// 初始化页面
|
async initPage() {
|
// 获取URL参数
|
this.vehicleNo = this.$route.query.vehicle || '';
|
this.evaluationForm.vehicleNo = this.vehicleNo;
|
|
// 检查是否在微信环境中
|
if (this.isWechatBrowser()) {
|
await this.handleWechatAuth();
|
}
|
|
// 加载评价维度
|
await this.loadDimensions();
|
},
|
|
// 判断是否为微信浏览器
|
isWechatBrowser() {
|
const ua = navigator.userAgent.toLowerCase();
|
return ua.indexOf('micromessenger') !== -1;
|
},
|
|
// 处理微信授权
|
async handleWechatAuth() {
|
const code = this.$route.query.code;
|
if (code) {
|
try {
|
const response = await getWechatUserInfo(code);
|
if (response.code === 200) {
|
const userInfo = response.data;
|
this.evaluationForm.wechatOpenid = userInfo.openid;
|
this.evaluationForm.wechatNickname = userInfo.nickname;
|
this.evaluationForm.wechatAvatar = userInfo.headimgurl;
|
this.evaluationForm.wechatPhone = userInfo.phone || '';
|
}
|
} catch (error) {
|
console.error('获取微信用户信息失败:', error);
|
}
|
}
|
},
|
|
// 加载评价维度
|
async loadDimensions() {
|
try {
|
const response = await getEvaluationDimensions();
|
if (response.code === 200) {
|
this.dimensions = response.data;
|
}
|
} catch (error) {
|
console.error('加载评价维度失败:', error);
|
this.$message.error('加载评价维度失败');
|
}
|
},
|
|
// 获取维度评分
|
getDimensionScore(dimensionId) {
|
const detail = this.evaluationForm.evaluationDetails.find(d => d.dimensionId === dimensionId);
|
return detail ? detail.score : 0;
|
},
|
|
// 更新维度评分
|
updateDimensionScore(dimensionId, score) {
|
let detail = this.evaluationForm.evaluationDetails.find(d => d.dimensionId === dimensionId);
|
if (!detail) {
|
detail = { dimensionId, score: 0 };
|
this.evaluationForm.evaluationDetails.push(detail);
|
}
|
detail.score = score;
|
},
|
|
// 获取维度选项
|
getDimensionOption(dimensionId) {
|
const detail = this.evaluationForm.evaluationDetails.find(d => d.dimensionId === dimensionId);
|
return detail ? detail.optionValue : '';
|
},
|
|
// 更新维度选项
|
updateDimensionOption(dimensionId, optionValue) {
|
let detail = this.evaluationForm.evaluationDetails.find(d => d.dimensionId === dimensionId);
|
if (!detail) {
|
detail = { dimensionId, optionValue: '' };
|
this.evaluationForm.evaluationDetails.push(detail);
|
}
|
detail.optionValue = optionValue;
|
},
|
|
// 获取维度文本
|
getDimensionText(dimensionId) {
|
const detail = this.evaluationForm.evaluationDetails.find(d => d.dimensionId === dimensionId);
|
return detail ? detail.textContent : '';
|
},
|
|
// 更新维度文本
|
updateDimensionText(dimensionId, textContent) {
|
let detail = this.evaluationForm.evaluationDetails.find(d => d.dimensionId === dimensionId);
|
if (!detail) {
|
detail = { dimensionId, textContent: '' };
|
this.evaluationForm.evaluationDetails.push(detail);
|
}
|
detail.textContent = textContent;
|
},
|
|
// 获取维度选项配置
|
getDimensionOptions(dimension) {
|
if (!dimension.options) return [];
|
try {
|
return JSON.parse(dimension.options);
|
} catch (error) {
|
return [];
|
}
|
},
|
|
// 提交评价
|
async submitEvaluation() {
|
try {
|
// 表单验证
|
await this.$refs.evaluationForm.validate();
|
|
// 检查必填的评价维度
|
for (const dimension of this.dimensions) {
|
if (dimension.isRequired === '1') {
|
const detail = this.evaluationForm.evaluationDetails.find(d => d.dimensionId === dimension.dimensionId);
|
if (!detail || (dimension.dimensionType === 'star' && !detail.score) ||
|
(dimension.dimensionType === 'select' && !detail.optionValue) ||
|
(dimension.dimensionType === 'text' && !detail.textContent)) {
|
this.$message.error(`请完成${dimension.dimensionName}的评价`);
|
return;
|
}
|
}
|
}
|
|
this.submitting = true;
|
|
// 提交评价
|
const response = await submitEvaluation(this.evaluationForm);
|
if (response.code === 200) {
|
this.resultMessage = response.msg;
|
this.showResult = true;
|
} else {
|
this.$message.error(response.msg || '提交失败,请重试');
|
}
|
} catch (error) {
|
console.error('提交评价失败:', error);
|
this.$message.error('提交失败,请重试');
|
} finally {
|
this.submitting = false;
|
}
|
},
|
|
// 重置表单
|
resetForm() {
|
this.showResult = false;
|
this.evaluationForm.customerName = '';
|
this.evaluationForm.customerPhone = '';
|
this.evaluationForm.evaluationDetails = [];
|
this.$refs.evaluationForm.resetFields();
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.evaluation-container {
|
max-width: 600px;
|
margin: 0 auto;
|
padding: 8px;
|
background-color: #f5f5f5;
|
min-height: 100vh;
|
}
|
|
.evaluation-header {
|
text-align: center;
|
margin-bottom: 12px;
|
padding: 12px;
|
background: white;
|
border-radius: 6px;
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
}
|
|
.evaluation-header h1 {
|
color: #333;
|
margin: 0 0 6px 0;
|
font-size: 20px;
|
}
|
|
.evaluation-header p {
|
color: #666;
|
margin: 0;
|
font-size: 14px;
|
}
|
|
.vehicle-info {
|
background: white;
|
padding: 8px 12px;
|
border-radius: 6px;
|
margin-bottom: 12px;
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
}
|
|
.info-item {
|
display: flex;
|
align-items: center;
|
}
|
|
.label {
|
font-weight: bold;
|
color: #333;
|
margin-right: 8px;
|
font-size: 14px;
|
}
|
|
.value {
|
color: #666;
|
font-size: 14px;
|
}
|
|
.evaluation-form {
|
background: white;
|
padding: 12px;
|
border-radius: 6px;
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
}
|
|
.form-section {
|
margin-bottom: 16px;
|
}
|
|
.form-section h3 {
|
color: #333;
|
margin: 0 0 12px 0;
|
padding-bottom: 6px;
|
border-bottom: 1px solid #409EFF;
|
font-size: 16px;
|
}
|
|
.dimension-item {
|
margin-bottom: 12px;
|
padding: 8px;
|
border: 1px solid #e4e7ed;
|
border-radius: 4px;
|
background-color: #fafafa;
|
}
|
|
.dimension-title {
|
font-weight: bold;
|
color: #333;
|
margin-bottom: 4px;
|
font-size: 14px;
|
}
|
|
.required {
|
color: #f56c6c;
|
margin-left: 3px;
|
}
|
|
.dimension-desc {
|
color: #666;
|
font-size: 12px;
|
margin-bottom: 8px;
|
}
|
|
/* 星级评价内联布局 */
|
.star-rating-inline {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
flex-wrap: wrap;
|
gap: 8px;
|
}
|
|
.dimension-title-inline {
|
font-weight: bold;
|
color: #333;
|
font-size: 14px;
|
flex-shrink: 0;
|
}
|
|
.star-rating-content {
|
flex: 1;
|
min-width: 200px;
|
}
|
|
.star-rating, .select-rating, .text-rating {
|
margin-top: 6px;
|
}
|
|
/* 优化星级评分显示 */
|
.star-rating .el-rate {
|
font-size: 18px;
|
}
|
|
.star-rating .el-rate__text {
|
font-size: 12px;
|
margin-left: 8px;
|
}
|
|
/* 优化选择评价显示 */
|
.select-rating .el-radio {
|
margin-right: 12px;
|
margin-bottom: 4px;
|
}
|
|
.select-rating .el-radio__label {
|
font-size: 13px;
|
}
|
|
/* 优化文本评价显示 */
|
.text-rating .el-textarea__inner {
|
font-size: 13px;
|
min-height: 60px !important;
|
}
|
|
/* 优化表单项间距 */
|
.el-form-item {
|
margin-bottom: 12px;
|
}
|
|
.el-form-item__label {
|
font-size: 13px;
|
line-height: 28px;
|
}
|
|
.el-input__inner {
|
font-size: 13px;
|
height: 32px;
|
line-height: 32px;
|
}
|
|
.form-actions {
|
text-align: center;
|
margin-top: 16px;
|
}
|
|
.form-actions .el-button {
|
padding: 10px 30px;
|
font-size: 14px;
|
}
|
|
.result-page {
|
position: fixed;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
background: rgba(0,0,0,0.5);
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
z-index: 1000;
|
}
|
|
.result-content {
|
background: white;
|
padding: 30px;
|
border-radius: 8px;
|
text-align: center;
|
max-width: 350px;
|
width: 90%;
|
}
|
|
.result-icon {
|
margin-bottom: 16px;
|
}
|
|
.result-message {
|
font-size: 16px;
|
color: #333;
|
margin-bottom: 20px;
|
}
|
|
.result-actions {
|
text-align: center;
|
}
|
|
/* 移动端适配 */
|
@media (max-width: 768px) {
|
.evaluation-container {
|
padding: 6px;
|
}
|
|
.evaluation-header {
|
padding: 10px;
|
margin-bottom: 8px;
|
}
|
|
.evaluation-header h1 {
|
font-size: 18px;
|
}
|
|
.evaluation-header p {
|
font-size: 13px;
|
}
|
|
.evaluation-form {
|
padding: 10px;
|
}
|
|
.dimension-item {
|
padding: 6px;
|
margin-bottom: 8px;
|
}
|
|
.form-section {
|
margin-bottom: 12px;
|
}
|
|
.form-section h3 {
|
font-size: 15px;
|
margin-bottom: 8px;
|
}
|
|
.dimension-title {
|
font-size: 13px;
|
}
|
|
.dimension-desc {
|
font-size: 11px;
|
}
|
|
.star-rating .el-rate {
|
font-size: 16px;
|
}
|
|
/* 移动端星级评价内联布局 */
|
.star-rating-inline {
|
flex-direction: column;
|
align-items: flex-start;
|
gap: 6px;
|
}
|
|
.dimension-title-inline {
|
font-size: 13px;
|
}
|
|
.star-rating-content {
|
min-width: auto;
|
width: 100%;
|
}
|
|
.select-rating .el-radio {
|
margin-right: 8px;
|
}
|
|
.select-rating .el-radio__label {
|
font-size: 12px;
|
}
|
|
.text-rating .el-textarea__inner {
|
font-size: 12px;
|
min-height: 50px !important;
|
}
|
|
.el-form-item {
|
margin-bottom: 8px;
|
}
|
|
.el-form-item__label {
|
font-size: 12px;
|
line-height: 26px;
|
}
|
|
.el-input__inner {
|
font-size: 12px;
|
height: 30px;
|
line-height: 30px;
|
}
|
|
.form-actions {
|
margin-top: 12px;
|
}
|
|
.form-actions .el-button {
|
padding: 8px 24px;
|
font-size: 13px;
|
}
|
}
|
|
/* 超小屏幕适配 */
|
@media (max-width: 480px) {
|
.evaluation-container {
|
padding: 4px;
|
}
|
|
.evaluation-header {
|
padding: 8px;
|
}
|
|
.evaluation-form {
|
padding: 8px;
|
}
|
|
.dimension-item {
|
padding: 4px;
|
}
|
|
.star-rating .el-rate {
|
font-size: 14px;
|
}
|
|
.text-rating .el-textarea__inner {
|
min-height: 40px !important;
|
}
|
}
|
</style>
|