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

331 lines
7.9 KiB

1 day ago
2 months ago
2 months ago
2 months ago
1 day ago
2 months ago
2 months ago
  1. <template>
  2. <view class="page__view highlight">
  3. <!-- 导航栏 -->
  4. <navbar title="活动详情" leftClick @leftClick="$utils.navigateBack" />
  5. <view class="tabs">
  6. <uv-tabs
  7. :list="tabs"
  8. :scrollable="false"
  9. lineColor="#00A9FF"
  10. lineWidth="48rpx"
  11. lineHeight="4rpx"
  12. :activeStyle="{
  13. 'font-family': 'PingFang SC',
  14. 'font-weight': 500,
  15. 'font-size': '32rpx',
  16. 'line-height': 1.4,
  17. 'color': '#00A9FF',
  18. }"
  19. :inactiveStyle="{
  20. 'font-family': 'PingFang SC',
  21. 'font-weight': 400,
  22. 'font-size': '32rpx',
  23. 'line-height': 1.4,
  24. 'color': '#191919',
  25. }"
  26. @click="clickTabs"
  27. ></uv-tabs>
  28. </view>
  29. <scroll-view type="custom" scroll-y="true" :scroll-into-view="scrollIntoView" class="scroll-view">
  30. <view class="scroll-view-content">
  31. <view class="cover-img">
  32. <image class="img" src="@/static/image/temp-20.png" mode="aspectFill"></image>
  33. </view>
  34. <view class="section" id="highlights">
  35. <view class="flex section-header">
  36. <view class="flex">
  37. <view class="flex icon">
  38. <image class="img" src="@/static/image/icon-mark.png" mode="widthFix"></image>
  39. </view>
  40. <view>活动掠影</view>
  41. </view>
  42. <view class="btn" @click="onMark">标记有我</view>
  43. </view>
  44. <view class="section-content highlights">
  45. <view class="highlights-item" v-for="(image, idx) in detail.highlights" :key="idx">
  46. <image class="img" :src="image" mode="aspectFill" @click="previewImage(detail.highlights, idx)"></image>
  47. </view>
  48. </view>
  49. </view>
  50. <view class="section" id="thoughts">
  51. <view class="flex section-header">
  52. <view>学员心得</view>
  53. <view class="btn" @click="onAdd">新增心得</view>
  54. </view>
  55. <view class="section-content thoughts">
  56. <view class="card" v-for="item in detail.thoughts" :key="item.id">
  57. <commentCard :data="item" @change="onCommentChange"></commentCard>
  58. </view>
  59. </view>
  60. </view>
  61. <view class="section report" id="report">
  62. <view class="section-header">行后报告</view>
  63. <view class="section-content report">
  64. <!-- todo -->
  65. <button class="btn" @click="jumpToExport">点击查看详情</button>
  66. </view>
  67. </view>
  68. </view>
  69. </scroll-view>
  70. <markPopup ref="markPopup"></markPopup>
  71. <record-form-popup ref="recordFormPopup" @submitted="getData"></record-form-popup>
  72. <posterPopup ref="posterPopup"></posterPopup>
  73. <view class="flex bottom">
  74. <button class="flex btn btn-palin" @click="openPosterPopup">生成海报</button>
  75. <button class="flex btn btn-primary" @click="onApplyEmail">申请邮件</button>
  76. </view>
  77. </view>
  78. </template>
  79. <script>
  80. // import commentCard from '@/pages_order/comment/commentCard.vue'
  81. import commentCard from './commentCard.vue'
  82. import markPopup from '@/pages_order/growing/activity/markPopup.vue'
  83. import recordFormPopup from '@/pages_order/comment/recordFormPopup.vue'
  84. import posterPopup from '@/components/base/posterPopup.vue'
  85. export default {
  86. components: {
  87. commentCard,
  88. markPopup,
  89. recordFormPopup,
  90. posterPopup,
  91. },
  92. data() {
  93. return {
  94. id: null,
  95. tabs: [
  96. { id: 'highlights', name: '活动掠影' },
  97. { id: 'thoughts', name: '学员心得' },
  98. { id: 'report', name: '行后报告' },
  99. ],
  100. current: 0,
  101. detail: {},
  102. scrollIntoView: null,
  103. }
  104. },
  105. onLoad(arg) {
  106. const { id, shareId } = arg
  107. if (shareId) {
  108. uni.setStorageSync('shareId', shareId)
  109. }
  110. if (shareId && !uni.getStorageSync('token')) {
  111. uni.navigateTo({
  112. url: '/pages_order/auth/wxLogin'
  113. })
  114. return
  115. }
  116. this.id = id
  117. this.getData()
  118. },
  119. methods: {
  120. async getData() {
  121. try {
  122. const result = await this.$fetch('queryExperienceById', { recordId: this.id })
  123. const { activityId, imageContentList, experienceList } = result
  124. this.detail = {
  125. activityId,
  126. highlights: imageContentList.reduce((arr, item) => {
  127. return arr.concat(item.image?.split?.(',') || [])
  128. }, []),
  129. thoughts: experienceList,
  130. // todo: check key about "行后报告"
  131. }
  132. } catch (err) {
  133. }
  134. },
  135. //点击tab栏
  136. clickTabs({ index }) {
  137. this.current = index
  138. this.scrollIntoView = this.tabs[this.current].id
  139. },
  140. onCommentChange() {
  141. // todo: refresh comment list
  142. },
  143. openPosterPopup() {
  144. const path = `/pages_order/growing/activity/index?id=${this.id}&shareId=${this.userInfo.id}`
  145. this.$refs.posterPopup.open(path)
  146. },
  147. onApplyEmail() {
  148. this.$utils.navigateTo(`/pages_order/growing/activity/applyEmail?id=${this.id}`)
  149. },
  150. jumpToExport() {
  151. uni.navigateTo({
  152. url: `/pages_order/growing/activity/export?id=${this.id}`
  153. })
  154. },
  155. onMark() {
  156. this.$refs.markPopup.open(this.detail.activityId)
  157. },
  158. onAdd() {
  159. this.$refs.recordFormPopup.open()
  160. },
  161. previewImage(arr, index) {
  162. uni.previewImage({
  163. urls: arr,
  164. current: arr[index], // 当前显示图片的链接
  165. });
  166. },
  167. },
  168. }
  169. </script>
  170. <style scoped lang="scss">
  171. .tabs {
  172. background: #D8F2FF;
  173. }
  174. .scroll-view {
  175. $tab-height: 44px;
  176. $bottom-height: 73px;
  177. height: calc(100vh - env(safe-area-inset-bottom) - #{$bottom-height} - #{$tab-height} - #{$navbar-height} - var(--status-bar-height) - 20rpx);
  178. &-content {
  179. padding: 32rpx;
  180. }
  181. }
  182. .cover-img {
  183. width: 100%;
  184. height: 348rpx;
  185. border-radius: 12rpx;
  186. overflow: hidden;
  187. .img {
  188. width: 100%;
  189. height: 100%;
  190. }
  191. }
  192. .section {
  193. margin-top: 32rpx;
  194. &-header {
  195. justify-content: space-between;
  196. font-size: 36rpx;
  197. font-weight: 600;
  198. color: #080808;
  199. .icon {
  200. margin-right: 24rpx;
  201. width: 36rpx;
  202. height: 36rpx;
  203. background: #080808;
  204. border-radius: 50%;
  205. overflow: hidden;
  206. .img {
  207. width: 24rpx;
  208. height: auto;
  209. }
  210. }
  211. .btn {
  212. padding: 6rpx 22rpx;
  213. font-family: PingFang SC;
  214. font-size: 28rpx;
  215. font-weight: 500;
  216. line-height: 1.5;
  217. color: #FFFFFF;
  218. background: linear-gradient(to right, #21FEEC, #019AF9);
  219. border: 2rpx solid #00A9FF;
  220. border-radius: 30rpx;
  221. }
  222. }
  223. &-content {
  224. }
  225. }
  226. .highlights {
  227. margin-top: 18rpx;
  228. display: grid;
  229. grid-template-columns: repeat(3, 1fr);
  230. gap: 16rpx;
  231. &-item {
  232. min-width: 0;
  233. height: 304rpx;
  234. border: 2rpx solid #CDCDCD;
  235. border-radius: 12rpx;
  236. overflow: hidden;
  237. .img {
  238. width: 100%;
  239. height: 100%;
  240. }
  241. }
  242. }
  243. .thoughts {
  244. margin-top: 24rpx;
  245. .card + .card {
  246. margin-top: 24rpx;
  247. }
  248. }
  249. .report {
  250. margin-top: 24rpx;
  251. }
  252. .bottom {
  253. position: fixed;
  254. left: 0;
  255. bottom: 0;
  256. z-index: 999;
  257. justify-content: space-between;
  258. column-gap: 32rpx;
  259. width: 100vw;
  260. padding: 32rpx 40rpx;
  261. padding-bottom: calc(env(safe-area-inset-bottom) + 32rpx);
  262. background: #FFFFFF;
  263. box-sizing: border-box;
  264. .btn {
  265. flex: 1;
  266. font-size: 36rpx;
  267. font-weight: 500;
  268. border-radius: 41rpx;
  269. line-height: 1.4;
  270. &-palin {
  271. padding: 14rpx 0;
  272. color: #252545;
  273. border: 2rpx solid #252545;
  274. }
  275. &-primary {
  276. padding: 14rpx 0;
  277. color: #FFFFFF;
  278. background: linear-gradient(to right, #21FEEC, #019AF9);
  279. border: 2rpx solid #00A9FF;
  280. }
  281. }
  282. }
  283. </style>