@ -0,0 +1,308 @@ | |||||
<template> | |||||
<view> | |||||
<uv-popup ref="popup" mode="bottom" bgColor="none" > | |||||
<view class="popup__view"> | |||||
<view class="flex header"> | |||||
<view class="title">评价</view> | |||||
<button class="btn" @click="close">关闭</button> | |||||
</view> | |||||
<view class="form"> | |||||
<uv-form | |||||
ref="form" | |||||
:model="form" | |||||
:rules="rules" | |||||
errorType="toast" | |||||
> | |||||
<view class="section"> | |||||
<productCard :data="detail"></productCard> | |||||
</view> | |||||
<view class="section"> | |||||
<view class="form-item"> | |||||
<uv-form-item prop="tripNum" :customStyle="formItemStyle"> | |||||
<view class="flex row"> | |||||
<view class="form-item-label">行程</view> | |||||
<view class="form-item-content"> | |||||
<formRate v-model="form.tripNum"></formRate> | |||||
</view> | |||||
</view> | |||||
</uv-form-item> | |||||
</view> | |||||
<view class="form-item"> | |||||
<uv-form-item prop="spotNum" :customStyle="formItemStyle"> | |||||
<view class="flex row"> | |||||
<view class="form-item-label">景点</view> | |||||
<view class="form-item-content"> | |||||
<formRate v-model="form.spotNum"></formRate> | |||||
</view> | |||||
</view> | |||||
</uv-form-item> | |||||
</view> | |||||
<view class="form-item"> | |||||
<uv-form-item prop="mentorNum" :customStyle="formItemStyle"> | |||||
<view class="flex row"> | |||||
<view class="form-item-label">导师</view> | |||||
<view class="form-item-content"> | |||||
<formRate v-model="form.mentorNum"></formRate> | |||||
</view> | |||||
</view> | |||||
</uv-form-item> | |||||
</view> | |||||
</view> | |||||
<view class="form-item"> | |||||
<uv-form-item prop="content" :customStyle="formItemStyle"> | |||||
<view class="form-item-content"> | |||||
<view class="tags"> | |||||
<view | |||||
v-for="(item, oIdx) in options" :key="oIdx" | |||||
:class="['tag', item === form.content ? 'is-active' : '']" | |||||
@click="onSelectContent(item)" | |||||
> | |||||
{{ item }} | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</uv-form-item> | |||||
</view> | |||||
</uv-form> | |||||
</view> | |||||
<view class="footer"> | |||||
<button class="flex btn" @click="onPublish">发布</button> | |||||
</view> | |||||
</view> | |||||
</uv-popup> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
import productCard from '@/pages_order/order/components/productCard.vue' | |||||
import formRate from '@/pages_order/components/formRate.vue' | |||||
export default { | |||||
components: { | |||||
productCard, | |||||
formRate, | |||||
}, | |||||
data() { | |||||
return { | |||||
id: null, | |||||
// todo: fetch | |||||
detail: {}, | |||||
form: { | |||||
tripNum: null, | |||||
spotNum: null, | |||||
mentorNum: null, | |||||
content: null, | |||||
}, | |||||
rules: { | |||||
'tripNum': { | |||||
type: 'number', | |||||
required: true, | |||||
message: '请为行程打分', | |||||
}, | |||||
'spotNum': { | |||||
type: 'number', | |||||
required: true, | |||||
message: '请为景点打分', | |||||
}, | |||||
'mentorNum': { | |||||
type: 'number', | |||||
required: true, | |||||
message: '请为导师打分', | |||||
}, | |||||
'content': { | |||||
type: 'string', | |||||
required: true, | |||||
message: '请选择评语', | |||||
}, | |||||
}, | |||||
// todo: fetch | |||||
options: [], | |||||
} | |||||
}, | |||||
methods: { | |||||
async getData() { | |||||
// todo: fetch order product | |||||
}, | |||||
async open(id) { | |||||
this.id = id | |||||
await this.getData() | |||||
this.form = { | |||||
tripNum: null, | |||||
spotNum: null, | |||||
mentorNum: null, | |||||
content: null, | |||||
} | |||||
this.$refs.popup.open() | |||||
}, | |||||
close() { | |||||
this.$refs.popup.close() | |||||
}, | |||||
onSelectContent(content) { | |||||
this.form.content = content | |||||
}, | |||||
async onPublish() { | |||||
try { | |||||
await this.$refs.form.validate() | |||||
const { | |||||
} = this.form | |||||
const params = { | |||||
} | |||||
// todo: fetch | |||||
// await this.$fetch('updateAddress', params) | |||||
uni.showToast({ | |||||
icon: 'success', | |||||
title: '发布成功', | |||||
}); | |||||
this.$emit('submitted') | |||||
this.close() | |||||
} catch (err) { | |||||
console.log('onSave err', err) | |||||
} | |||||
}, | |||||
}, | |||||
} | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.popup__view { | |||||
width: 100vw; | |||||
display: flex; | |||||
flex-direction: column; | |||||
box-sizing: border-box; | |||||
background: #FFFFFF; | |||||
border-top-left-radius: 32rpx; | |||||
border-top-right-radius: 32rpx; | |||||
} | |||||
.header { | |||||
position: relative; | |||||
width: 100%; | |||||
padding: 24rpx 0; | |||||
box-sizing: border-box; | |||||
border-bottom: 2rpx solid #EEEEEE; | |||||
.title { | |||||
font-family: PingFang SC; | |||||
font-weight: 500; | |||||
font-size: 34rpx; | |||||
line-height: 1.4; | |||||
color: #181818; | |||||
} | |||||
.btn { | |||||
font-family: PingFang SC; | |||||
font-weight: 500; | |||||
font-size: 32rpx; | |||||
line-height: 1.4; | |||||
color: #8B8B8B; | |||||
position: absolute; | |||||
top: 26rpx; | |||||
left: 40rpx; | |||||
} | |||||
} | |||||
.section { | |||||
& + & { | |||||
margin-top: 24rpx; | |||||
} | |||||
} | |||||
.form { | |||||
max-height: 75vh; | |||||
padding: 32rpx 40rpx; | |||||
box-sizing: border-box; | |||||
overflow-y: auto; | |||||
&-item { | |||||
&-label { | |||||
margin-bottom: 14rpx; | |||||
display: flex; | |||||
align-items: center; | |||||
font-family: PingFang SC; | |||||
font-weight: 400; | |||||
font-size: 26rpx; | |||||
line-height: 1.4; | |||||
color: #181818; | |||||
.icon { | |||||
margin-right: 8rpx; | |||||
width: 16rpx; | |||||
height: auto; | |||||
} | |||||
} | |||||
&-content { | |||||
} | |||||
} | |||||
} | |||||
.row { | |||||
justify-content: space-between; | |||||
padding: 4rpx 0; | |||||
& + & { | |||||
margin-top: 4rpx; | |||||
} | |||||
.form-label { | |||||
margin: 0; | |||||
} | |||||
} | |||||
.tags { | |||||
display: grid; | |||||
grid-template-columns: repeat(2, 1fr); | |||||
gap: 24rpx; | |||||
} | |||||
.tag { | |||||
min-width: 0; | |||||
padding: 16rpx; | |||||
font-size: 26rpx; | |||||
line-height: 1.4; | |||||
color: #252545; | |||||
background: #F5F8FF; | |||||
border-radius: 24rpx; | |||||
&.is-active { | |||||
color: #FFFFFF; | |||||
background: #00A9FF; | |||||
} | |||||
} | |||||
.footer { | |||||
width: 100%; | |||||
padding: 32rpx 40rpx; | |||||
box-sizing: border-box; | |||||
border-top: 2rpx solid #F1F1F1; | |||||
.btn { | |||||
width: 100%; | |||||
padding: 14rpx 0; | |||||
box-sizing: border-box; | |||||
font-family: PingFang SC; | |||||
font-weight: 500; | |||||
font-size: 36rpx; | |||||
line-height: 1.4; | |||||
color: #FFFFFF; | |||||
background-image: linear-gradient(to right, #21FEEC, #019AF9); | |||||
border: 2rpx solid #00A9FF; | |||||
border-radius: 41rpx; | |||||
} | |||||
} | |||||
</style> |
@ -1,270 +0,0 @@ | |||||
<template> | |||||
<view class="page__view"> | |||||
<navbar title="立即评价" leftClick @leftClick="$utils.navigateBack" color="#191919" bgColor="#F3F2F7" /> | |||||
<view class="main form"> | |||||
<uv-form | |||||
ref="form" | |||||
:model="form" | |||||
:rules="rules" | |||||
errorType="toast" | |||||
> | |||||
<view class="card info"> | |||||
<view class="card-header">评价信息</view> | |||||
<view class="form-item"> | |||||
<uv-form-item prop="content" :customStyle="formItemStyle"> | |||||
<view class="form-item-label">评价内容</view> | |||||
<view class="form-item-content"> | |||||
<formTextarea v-model="form.content"></formTextarea> | |||||
</view> | |||||
</uv-form-item> | |||||
</view> | |||||
<view class="form-item"> | |||||
<uv-form-item prop="images" :customStyle="formItemStyle"> | |||||
<view class="form-item-label">上传图片/视频(选填)</view> | |||||
<view class="form-item-content"> | |||||
<formUpload v-model="form.images"></formUpload> | |||||
</view> | |||||
</uv-form-item> | |||||
</view> | |||||
</view> | |||||
<view class="card"> | |||||
<view class="form-item"> | |||||
<uv-form-item prop="productNum" :customStyle="formItemStyle"> | |||||
<view class="flex row"> | |||||
<view class="form-item-label">产品服务度</view> | |||||
<view class="form-item-content"> | |||||
<uv-rate v-model="form.productNum" size="48rpx" gutter="16rpx" activeColor="#F7BA1E" :allowHalf="true" :minCount="0.5" ></uv-rate> | |||||
</view> | |||||
</view> | |||||
</uv-form-item> | |||||
</view> | |||||
<view class="form-item"> | |||||
<uv-form-item prop="paperNum" :customStyle="formItemStyle"> | |||||
<view class="flex row"> | |||||
<view class="form-item-label">问卷体验</view> | |||||
<view class="form-item-content"> | |||||
<uv-rate v-model="form.paperNum" size="48rpx" gutter="16rpx" activeColor="#F7BA1E" :allowHalf="true" :minCount="0.5" ></uv-rate> | |||||
</view> | |||||
</view> | |||||
</uv-form-item> | |||||
</view> | |||||
<view class="form-item"> | |||||
<uv-form-item prop="logisticsNum" :customStyle="formItemStyle"> | |||||
<view class="flex row"> | |||||
<view class="form-item-label">物流速度</view> | |||||
<view class="form-item-content"> | |||||
<uv-rate v-model="form.logisticsNum" size="48rpx" gutter="16rpx" activeColor="#F7BA1E" :allowHalf="true" :minCount="0.5" ></uv-rate> | |||||
</view> | |||||
</view> | |||||
</uv-form-item> | |||||
</view> | |||||
</view> | |||||
</uv-form> | |||||
</view> | |||||
<view class="bottom"> | |||||
<button class="btn" @click="onSubmit">提交申请</button> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
import { mapState } from 'vuex' | |||||
import formTextarea from '@/pages_order/components/formTextarea.vue' | |||||
import formUpload from '@/pages_order/components/formUpload.vue' | |||||
export default { | |||||
components: { | |||||
formTextarea, | |||||
formUpload, | |||||
}, | |||||
data() { | |||||
return { | |||||
orderId: null, | |||||
form: { | |||||
content: null, | |||||
images: [], | |||||
productNum: null, | |||||
paperNum: null, | |||||
logisticsNum: null, | |||||
}, | |||||
rules: { | |||||
'content': { | |||||
type: 'string', | |||||
required: true, | |||||
message: '请输入评价', | |||||
}, | |||||
'productNum': { | |||||
type: 'number', | |||||
required: true, | |||||
message: '请为【产品服务度】打分', | |||||
}, | |||||
'paperNum': { | |||||
type: 'number', | |||||
required: true, | |||||
message: '请为【问卷体验】打分', | |||||
}, | |||||
'logisticsNum': { | |||||
type: 'number', | |||||
required: true, | |||||
message: '请为【物流速度】打分', | |||||
}, | |||||
}, | |||||
formItemStyle: { padding: 0 }, | |||||
} | |||||
}, | |||||
computed: { | |||||
...mapState(['userInfo']), | |||||
}, | |||||
onLoad(arg) { | |||||
const { orderId } = arg | |||||
this.orderId = orderId | |||||
}, | |||||
methods: { | |||||
async onSubmit() { | |||||
try { | |||||
await this.$refs.form.validate() | |||||
const { | |||||
content, | |||||
images, | |||||
productNum, | |||||
paperNum, | |||||
logisticsNum, | |||||
} = this.form | |||||
const params = { | |||||
orderId: this.orderId, | |||||
content, | |||||
image: images.join(','), | |||||
productNum, | |||||
paperNum, | |||||
logisticsNum, | |||||
} | |||||
await this.$fetch('evaluateOrder', params) | |||||
uni.showToast({ | |||||
icon: 'success', | |||||
title: '提交成功', | |||||
}); | |||||
setTimeout(() => { | |||||
this.$utils.navigateBack() | |||||
}, 800) | |||||
} catch (err) { | |||||
console.log('onSubmit err', err) | |||||
} | |||||
}, | |||||
}, | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.page__view { | |||||
width: 100vw; | |||||
min-height: 100vh; | |||||
background-color: $uni-bg-color; | |||||
position: relative; | |||||
/deep/ .nav-bar__view { | |||||
position: fixed; | |||||
top: 0; | |||||
left: 0; | |||||
} | |||||
} | |||||
.main { | |||||
padding: calc(var(--status-bar-height) + 144rpx) 32rpx 236rpx 32rpx; | |||||
} | |||||
.card { | |||||
padding: 32rpx; | |||||
background: #FFFFFF; | |||||
border: 2rpx solid #FFFFFF; | |||||
border-radius: 32rpx; | |||||
& + & { | |||||
margin-top: 40rpx; | |||||
} | |||||
&-header { | |||||
font-family: PingFang SC; | |||||
font-weight: 500; | |||||
font-size: 36rpx; | |||||
line-height: 1.4; | |||||
color: #252545; | |||||
margin-bottom: 32rpx; | |||||
} | |||||
} | |||||
.form { | |||||
&-item { | |||||
border-bottom: 2rpx solid #EEEEEE; | |||||
&:last-child { | |||||
border: none; | |||||
} | |||||
& + & { | |||||
margin-top: 32rpx; | |||||
} | |||||
&-label { | |||||
font-family: PingFang SC; | |||||
font-weight: 400; | |||||
font-size: 26rpx; | |||||
line-height: 1.4; | |||||
color: #181818; | |||||
} | |||||
} | |||||
} | |||||
.info { | |||||
.form-item + .form-item { | |||||
margin-top: 40rpx; | |||||
} | |||||
.form-item-content { | |||||
margin-top: 16rpx; | |||||
} | |||||
} | |||||
.row { | |||||
justify-content: space-between; | |||||
} | |||||
.bottom { | |||||
position: fixed; | |||||
left: 0; | |||||
bottom: 0; | |||||
width: 100vw; | |||||
// height: 200rpx; | |||||
padding: 24rpx 40rpx; | |||||
padding-bottom: calc(env(safe-area-inset-bottom) + 24rpx); | |||||
background: #FFFFFF; | |||||
box-sizing: border-box; | |||||
.btn { | |||||
width: 100%; | |||||
padding: 16rpx 0; | |||||
box-sizing: border-box; | |||||
font-family: PingFang SC; | |||||
font-weight: 500; | |||||
font-size: 36rpx; | |||||
line-height: 1; | |||||
color: #FFFFFF; | |||||
background-image: linear-gradient(to right, #4B348F, #845CFA); | |||||
border-radius: 41rpx; | |||||
} | |||||
} | |||||
</style> |