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

356 lines
9.5 KiB

  1. <template>
  2. <view>
  3. <uv-popup ref="popup" mode="bottom" bgColor="none" :zIndex="1000000" @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="form-item">
  17. <uv-form-item prop="project" :customStyle="formItemStyle">
  18. <view class="form-item-label">
  19. <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image>
  20. 关联项目
  21. </view>
  22. <view class="form-item-content">
  23. <view class="flex row" @click="openRelatePojectPicker">
  24. <view v-if="form.project" class="text">{{ projectDesc }}</view>
  25. <view v-else class="text placeholder">请选择关联项目</view>
  26. <uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon>
  27. </view>
  28. <reloateProjectPopup ref="reloateProjectPopup" :options="projects" @confirm="onRelateProjectChange"></reloateProjectPopup>
  29. </view>
  30. </uv-form-item>
  31. </view>
  32. <view class="form-item">
  33. <uv-form-item prop="tripNum" :customStyle="formItemStyle">
  34. <view class="flex row">
  35. <view class="form-item-label">行程</view>
  36. <view class="form-item-content">
  37. <formRate v-model="form.tripNum"></formRate>
  38. </view>
  39. </view>
  40. </uv-form-item>
  41. </view>
  42. <view class="form-item">
  43. <uv-form-item prop="spotNum" :customStyle="formItemStyle">
  44. <view class="flex row">
  45. <view class="form-item-label">景点</view>
  46. <view class="form-item-content">
  47. <formRate v-model="form.spotNum"></formRate>
  48. </view>
  49. </view>
  50. </uv-form-item>
  51. </view>
  52. <view class="form-item">
  53. <uv-form-item prop="mentorNum" :customStyle="formItemStyle">
  54. <view class="flex row">
  55. <view class="form-item-label">导师</view>
  56. <view class="form-item-content">
  57. <formRate v-model="form.mentorNum"></formRate>
  58. </view>
  59. </view>
  60. </uv-form-item>
  61. </view>
  62. <view class="form-item">
  63. <uv-form-item prop="images" :customStyle="formItemStyle">
  64. <view class="form-item-label">上传图片</view>
  65. <view class="form-item-content">
  66. <formUpload v-model="form.images"></formUpload>
  67. </view>
  68. </uv-form-item>
  69. </view>
  70. <view class="form-item" v-for="(item, index) in questions" :key="item.id">
  71. <uv-form-item :prop="`texts[${index}]`" :customStyle="formItemStyle">
  72. <view class="form-item-label">
  73. <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image>
  74. {{ item.label }}
  75. </view>
  76. <view class="form-item-content">
  77. <formTextarea v-model="form.texts[index]"></formTextarea>
  78. </view>
  79. </uv-form-item>
  80. </view>
  81. </uv-form>
  82. </view>
  83. <view class="footer">
  84. <button class="flex btn" @click="onPublish">发布</button>
  85. </view>
  86. </view>
  87. </uv-popup>
  88. </view>
  89. </template>
  90. <script>
  91. import reloateProjectPopup from '@/pages_order/components/reloateProjectPopup.vue'
  92. import formTextarea from '@/pages_order/components/formTextarea.vue'
  93. import formUpload from '@/pages_order/components/formUpload.vue'
  94. import formRate from '@/pages_order/components/formRate.vue'
  95. export default {
  96. components: {
  97. reloateProjectPopup,
  98. formTextarea,
  99. formUpload,
  100. formRate,
  101. },
  102. data() {
  103. return {
  104. isShow: false,
  105. form: {
  106. project: null,
  107. tripNum: null,
  108. spotNum: null,
  109. mentorNum: null,
  110. images: [],
  111. texts: [],
  112. },
  113. rules: {
  114. // todo
  115. },
  116. projects: [],
  117. questions: [],
  118. }
  119. },
  120. computed: {
  121. projectDesc() {
  122. const { project } = this.form
  123. const target = this.projects?.find?.(item => item.id === project)
  124. return target?.name || ''
  125. },
  126. },
  127. methods: {
  128. getData() {
  129. // todo
  130. this.projects = [
  131. {
  132. id: '001',
  133. name: '亲子•坝上双草原6日 |乌兰布统+锡林郭勒+长城',
  134. },
  135. {
  136. id: '002',
  137. name: '青青草原•云中岭 |5-10公里AB线强度可选',
  138. },
  139. {
  140. id: '003',
  141. name: '新疆天山行7/9日丨醉美伊犁&吐鲁番双套餐',
  142. },
  143. {
  144. id: '004',
  145. name: '九色甘南|人间净土6日/7日深度游',
  146. },
  147. {
  148. id: '005',
  149. name: '北疆全景12日| 入疆首推!阿勒泰+伊犁+吐鲁番',
  150. },
  151. {
  152. id: '006',
  153. name: '塞上江南•神奇宁夏5日|穿越大漠与历史对话',
  154. },
  155. {
  156. id: '007',
  157. name: '尊享•天山环线9日| 伊犁全景+独库,头等舱大巴',
  158. },
  159. ]
  160. this.questions = [
  161. {
  162. id: '001',
  163. label: '这次研学之旅,整体给你留下了怎样的印象?用几个词或几句话简单概括一下',
  164. },
  165. {
  166. id: '002',
  167. label: '在整个行程中,你最喜欢的部分是哪里?为什么?',
  168. },
  169. {
  170. id: '003',
  171. label: '你觉得这次研学的行程安排是否合理?有没有哪些地方让你觉得特别满意或需要改进的?',
  172. },
  173. ]
  174. },
  175. async open() {
  176. await this.getData()
  177. const texts = this.questions.map(() => '')
  178. this.form = {
  179. project: null,
  180. tripNum: null,
  181. spotNum: null,
  182. mentorNum: null,
  183. images: [],
  184. texts,
  185. }
  186. this.$refs.popup.open()
  187. },
  188. close() {
  189. this.$refs.popup.close()
  190. },
  191. onPopupChange(e) {
  192. this.isShow = e.show
  193. },
  194. openRelatePojectPicker() {
  195. this.$refs.reloateProjectPopup.open(this.form.project?.id || null)
  196. },
  197. onRelateProjectChange(id) {
  198. this.form.project = id
  199. },
  200. async onPublish() {
  201. try {
  202. await this.$refs.form.validate()
  203. const {
  204. } = this.form
  205. const params = {
  206. }
  207. // todo: fetch
  208. // await this.$fetch('updateAddress', params)
  209. uni.showToast({
  210. icon: 'success',
  211. title: '发布成功',
  212. });
  213. this.$emit('submitted')
  214. this.close()
  215. } catch (err) {
  216. console.log('onSave err', err)
  217. }
  218. },
  219. },
  220. }
  221. </script>
  222. <style lang="scss" scoped>
  223. .popup__view {
  224. width: 100vw;
  225. display: flex;
  226. flex-direction: column;
  227. box-sizing: border-box;
  228. background: #FFFFFF;
  229. border-top-left-radius: 32rpx;
  230. border-top-right-radius: 32rpx;
  231. }
  232. .header {
  233. position: relative;
  234. width: 100%;
  235. padding: 24rpx 0;
  236. box-sizing: border-box;
  237. border-bottom: 2rpx solid #EEEEEE;
  238. .title {
  239. font-family: PingFang SC;
  240. font-weight: 500;
  241. font-size: 34rpx;
  242. line-height: 1.4;
  243. color: #181818;
  244. }
  245. .btn {
  246. font-family: PingFang SC;
  247. font-weight: 500;
  248. font-size: 32rpx;
  249. line-height: 1.4;
  250. color: #8B8B8B;
  251. position: absolute;
  252. top: 26rpx;
  253. left: 40rpx;
  254. }
  255. }
  256. .form {
  257. max-height: 75vh;
  258. padding: 32rpx 40rpx;
  259. box-sizing: border-box;
  260. overflow-y: auto;
  261. &-item {
  262. padding: 8rpx 0 6rpx 0;
  263. & + & {
  264. padding-top: 24rpx;
  265. border-top: 2rpx solid #EEEEEE;
  266. }
  267. &-label {
  268. margin-bottom: 14rpx;
  269. display: flex;
  270. align-items: center;
  271. font-family: PingFang SC;
  272. font-weight: 400;
  273. font-size: 26rpx;
  274. line-height: 1.4;
  275. color: #181818;
  276. .icon {
  277. margin-right: 8rpx;
  278. width: 16rpx;
  279. height: auto;
  280. }
  281. }
  282. &-content {
  283. .text {
  284. padding: 2rpx 0;
  285. font-family: PingFang SC;
  286. font-weight: 400;
  287. font-size: 32rpx;
  288. line-height: 1.4;
  289. &.placeholder {
  290. color: #C6C6C6;
  291. }
  292. }
  293. }
  294. }
  295. }
  296. .row {
  297. justify-content: space-between;
  298. .form-label {
  299. margin: 0;
  300. }
  301. }
  302. .footer {
  303. width: 100%;
  304. padding: 32rpx 40rpx;
  305. box-sizing: border-box;
  306. border-top: 2rpx solid #F1F1F1;
  307. .btn {
  308. width: 100%;
  309. padding: 14rpx 0;
  310. box-sizing: border-box;
  311. font-family: PingFang SC;
  312. font-weight: 500;
  313. font-size: 36rpx;
  314. line-height: 1.4;
  315. color: #FFFFFF;
  316. background-image: linear-gradient(to right, #21FEEC, #019AF9);
  317. border: 2rpx solid #00A9FF;
  318. border-radius: 41rpx;
  319. }
  320. }
  321. </style>