鸿宇研学生前端代码
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.

307 lines
6.9 KiB

  1. <template>
  2. <view>
  3. <uv-popup ref="popup" mode="bottom" bgColor="none" >
  4. <view class="popup__view">
  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. id: null,
  86. // todo: fetch
  87. detail: {},
  88. form: {
  89. tripNum: null,
  90. spotNum: null,
  91. mentorNum: null,
  92. content: null,
  93. },
  94. rules: {
  95. 'tripNum': {
  96. type: 'number',
  97. required: true,
  98. message: '请为行程打分',
  99. },
  100. 'spotNum': {
  101. type: 'number',
  102. required: true,
  103. message: '请为景点打分',
  104. },
  105. 'mentorNum': {
  106. type: 'number',
  107. required: true,
  108. message: '请为导师打分',
  109. },
  110. 'content': {
  111. type: 'string',
  112. required: true,
  113. message: '请选择评语',
  114. },
  115. },
  116. // todo: fetch
  117. options: [],
  118. }
  119. },
  120. methods: {
  121. async getData() {
  122. // todo: fetch order product
  123. },
  124. async open(id) {
  125. this.id = id
  126. await this.getData()
  127. this.form = {
  128. tripNum: null,
  129. spotNum: null,
  130. mentorNum: null,
  131. content: null,
  132. }
  133. this.$refs.popup.open()
  134. },
  135. close() {
  136. this.$refs.popup.close()
  137. },
  138. onSelectContent(content) {
  139. this.form.content = content
  140. },
  141. async onPublish() {
  142. try {
  143. await this.$refs.form.validate()
  144. const {
  145. } = this.form
  146. const params = {
  147. }
  148. // todo: fetch
  149. // await this.$fetch('updateAddress', params)
  150. uni.showToast({
  151. icon: 'success',
  152. title: '发布成功',
  153. });
  154. this.$emit('submitted')
  155. this.close()
  156. } catch (err) {
  157. console.log('onSave err', err)
  158. }
  159. },
  160. },
  161. }
  162. </script>
  163. <style lang="scss" scoped>
  164. .popup__view {
  165. width: 100vw;
  166. display: flex;
  167. flex-direction: column;
  168. box-sizing: border-box;
  169. background: #FFFFFF;
  170. border-top-left-radius: 32rpx;
  171. border-top-right-radius: 32rpx;
  172. }
  173. .header {
  174. position: relative;
  175. width: 100%;
  176. padding: 24rpx 0;
  177. box-sizing: border-box;
  178. border-bottom: 2rpx solid #EEEEEE;
  179. .title {
  180. font-family: PingFang SC;
  181. font-weight: 500;
  182. font-size: 34rpx;
  183. line-height: 1.4;
  184. color: #181818;
  185. }
  186. .btn {
  187. font-family: PingFang SC;
  188. font-weight: 500;
  189. font-size: 32rpx;
  190. line-height: 1.4;
  191. color: #8B8B8B;
  192. position: absolute;
  193. top: 26rpx;
  194. left: 40rpx;
  195. }
  196. }
  197. .section {
  198. & + & {
  199. margin-top: 24rpx;
  200. }
  201. }
  202. .form {
  203. max-height: 75vh;
  204. padding: 32rpx 40rpx;
  205. box-sizing: border-box;
  206. overflow-y: auto;
  207. &-item {
  208. &-label {
  209. margin-bottom: 14rpx;
  210. display: flex;
  211. align-items: center;
  212. font-family: PingFang SC;
  213. font-weight: 400;
  214. font-size: 26rpx;
  215. line-height: 1.4;
  216. color: #181818;
  217. .icon {
  218. margin-right: 8rpx;
  219. width: 16rpx;
  220. height: auto;
  221. }
  222. }
  223. &-content {
  224. }
  225. }
  226. }
  227. .row {
  228. justify-content: space-between;
  229. padding: 4rpx 0;
  230. & + & {
  231. margin-top: 4rpx;
  232. }
  233. .form-label {
  234. margin: 0;
  235. }
  236. }
  237. .tags {
  238. display: grid;
  239. grid-template-columns: repeat(2, 1fr);
  240. gap: 24rpx;
  241. }
  242. .tag {
  243. min-width: 0;
  244. padding: 16rpx;
  245. font-size: 26rpx;
  246. line-height: 1.4;
  247. color: #252545;
  248. background: #F5F8FF;
  249. border-radius: 24rpx;
  250. &.is-active {
  251. color: #FFFFFF;
  252. background: #00A9FF;
  253. }
  254. }
  255. .footer {
  256. width: 100%;
  257. padding: 32rpx 40rpx;
  258. box-sizing: border-box;
  259. border-top: 2rpx solid #F1F1F1;
  260. .btn {
  261. width: 100%;
  262. padding: 14rpx 0;
  263. box-sizing: border-box;
  264. font-family: PingFang SC;
  265. font-weight: 500;
  266. font-size: 36rpx;
  267. line-height: 1.4;
  268. color: #FFFFFF;
  269. background-image: linear-gradient(to right, #21FEEC, #019AF9);
  270. border: 2rpx solid #00A9FF;
  271. border-radius: 41rpx;
  272. }
  273. }
  274. </style>