鸿宇研学生前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

311 lines
7.1 KiB

  1. <template>
  2. <view>
  3. <uv-popup ref="popup" mode="bottom" bgColor="none" @change="onPopupChange">
  4. <view class="popup__view" v-if="isShow">
  5. <view class="flex header">
  6. <view class="title">评价</view>
  7. <button class="btn" @click="close">关闭</button>
  8. </view>
  9. <view class="form">
  10. <uv-form
  11. ref="form"
  12. :model="form"
  13. :rules="rules"
  14. errorType="toast"
  15. >
  16. <view class="section">
  17. <productCard :data="detail"></productCard>
  18. </view>
  19. <view class="section">
  20. <view class="form-item">
  21. <uv-form-item prop="tripNum" :customStyle="formItemStyle">
  22. <view class="flex row">
  23. <view class="form-item-label">行程</view>
  24. <view class="form-item-content">
  25. <formRate v-model="form.tripNum"></formRate>
  26. </view>
  27. </view>
  28. </uv-form-item>
  29. </view>
  30. <view class="form-item">
  31. <uv-form-item prop="spotNum" :customStyle="formItemStyle">
  32. <view class="flex row">
  33. <view class="form-item-label">景点</view>
  34. <view class="form-item-content">
  35. <formRate v-model="form.spotNum"></formRate>
  36. </view>
  37. </view>
  38. </uv-form-item>
  39. </view>
  40. <view class="form-item">
  41. <uv-form-item prop="mentorNum" :customStyle="formItemStyle">
  42. <view class="flex row">
  43. <view class="form-item-label">导师</view>
  44. <view class="form-item-content">
  45. <formRate v-model="form.mentorNum"></formRate>
  46. </view>
  47. </view>
  48. </uv-form-item>
  49. </view>
  50. </view>
  51. <view class="form-item">
  52. <uv-form-item prop="content" :customStyle="formItemStyle">
  53. <view class="form-item-content">
  54. <view class="tags">
  55. <view
  56. v-for="(item, oIdx) in options" :key="oIdx"
  57. :class="['tag', item === form.content ? 'is-active' : '']"
  58. @click="onSelectContent(item)"
  59. >
  60. {{ item }}
  61. </view>
  62. </view>
  63. </view>
  64. </uv-form-item>
  65. </view>
  66. </uv-form>
  67. </view>
  68. <view class="footer">
  69. <button class="flex btn" @click="onPublish">发布</button>
  70. </view>
  71. </view>
  72. </uv-popup>
  73. </view>
  74. </template>
  75. <script>
  76. import productCard from '@/pages_order/order/components/productCard.vue'
  77. import formRate from '@/pages_order/components/formRate.vue'
  78. export default {
  79. components: {
  80. productCard,
  81. formRate,
  82. },
  83. data() {
  84. return {
  85. isShow: false,
  86. id: null,
  87. // todo: fetch
  88. detail: {},
  89. form: {
  90. tripNum: null,
  91. spotNum: null,
  92. mentorNum: null,
  93. content: null,
  94. },
  95. rules: {
  96. 'tripNum': {
  97. type: 'number',
  98. required: true,
  99. message: '请为行程打分',
  100. },
  101. 'spotNum': {
  102. type: 'number',
  103. required: true,
  104. message: '请为景点打分',
  105. },
  106. 'mentorNum': {
  107. type: 'number',
  108. required: true,
  109. message: '请为导师打分',
  110. },
  111. 'content': {
  112. type: 'string',
  113. required: true,
  114. message: '请选择评语',
  115. },
  116. },
  117. // todo: fetch
  118. options: [],
  119. }
  120. },
  121. methods: {
  122. async getData() {
  123. // todo: fetch order product
  124. },
  125. async open(id) {
  126. this.id = id
  127. await this.getData()
  128. this.form = {
  129. tripNum: null,
  130. spotNum: null,
  131. mentorNum: null,
  132. content: null,
  133. }
  134. this.$refs.popup.open()
  135. },
  136. close() {
  137. this.$refs.popup.close()
  138. },
  139. onPopupChange(e) {
  140. this.isShow = e.show
  141. },
  142. onSelectContent(content) {
  143. this.form.content = content
  144. },
  145. async onPublish() {
  146. try {
  147. await this.$refs.form.validate()
  148. const {
  149. } = this.form
  150. const params = {
  151. }
  152. // todo: fetch
  153. // await this.$fetch('updateAddress', params)
  154. uni.showToast({
  155. icon: 'success',
  156. title: '发布成功',
  157. });
  158. this.$emit('submitted')
  159. this.close()
  160. } catch (err) {
  161. console.log('onSave err', err)
  162. }
  163. },
  164. },
  165. }
  166. </script>
  167. <style lang="scss" scoped>
  168. .popup__view {
  169. width: 100vw;
  170. display: flex;
  171. flex-direction: column;
  172. box-sizing: border-box;
  173. background: #FFFFFF;
  174. border-top-left-radius: 32rpx;
  175. border-top-right-radius: 32rpx;
  176. }
  177. .header {
  178. position: relative;
  179. width: 100%;
  180. padding: 24rpx 0;
  181. box-sizing: border-box;
  182. border-bottom: 2rpx solid #EEEEEE;
  183. .title {
  184. font-family: PingFang SC;
  185. font-weight: 500;
  186. font-size: 34rpx;
  187. line-height: 1.4;
  188. color: #181818;
  189. }
  190. .btn {
  191. font-family: PingFang SC;
  192. font-weight: 500;
  193. font-size: 32rpx;
  194. line-height: 1.4;
  195. color: #8B8B8B;
  196. position: absolute;
  197. top: 26rpx;
  198. left: 40rpx;
  199. }
  200. }
  201. .section {
  202. & + & {
  203. margin-top: 24rpx;
  204. }
  205. }
  206. .form {
  207. max-height: 75vh;
  208. padding: 32rpx 40rpx;
  209. box-sizing: border-box;
  210. overflow-y: auto;
  211. &-item {
  212. &-label {
  213. margin-bottom: 14rpx;
  214. display: flex;
  215. align-items: center;
  216. font-family: PingFang SC;
  217. font-weight: 400;
  218. font-size: 26rpx;
  219. line-height: 1.4;
  220. color: #181818;
  221. .icon {
  222. margin-right: 8rpx;
  223. width: 16rpx;
  224. height: auto;
  225. }
  226. }
  227. &-content {
  228. }
  229. }
  230. }
  231. .row {
  232. justify-content: space-between;
  233. padding: 4rpx 0;
  234. & + & {
  235. margin-top: 4rpx;
  236. }
  237. .form-label {
  238. margin: 0;
  239. }
  240. }
  241. .tags {
  242. display: grid;
  243. grid-template-columns: repeat(2, 1fr);
  244. gap: 24rpx;
  245. }
  246. .tag {
  247. min-width: 0;
  248. padding: 16rpx;
  249. font-size: 26rpx;
  250. line-height: 1.4;
  251. color: #252545;
  252. background: #F5F8FF;
  253. border-radius: 24rpx;
  254. &.is-active {
  255. color: #FFFFFF;
  256. background: #00A9FF;
  257. }
  258. }
  259. .footer {
  260. width: 100%;
  261. padding: 32rpx 40rpx;
  262. box-sizing: border-box;
  263. border-top: 2rpx solid #F1F1F1;
  264. .btn {
  265. width: 100%;
  266. padding: 14rpx 0;
  267. box-sizing: border-box;
  268. font-family: PingFang SC;
  269. font-weight: 500;
  270. font-size: 36rpx;
  271. line-height: 1.4;
  272. color: #FFFFFF;
  273. background-image: linear-gradient(to right, #21FEEC, #019AF9);
  274. border: 2rpx solid #00A9FF;
  275. border-radius: 41rpx;
  276. }
  277. }
  278. </style>