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

235 lines
5.1 KiB

  1. <template>
  2. <view class="page__view highlight">
  3. <navbar :title="liveInfo.title" leftClick @leftClick="$utils.navigateBack" />
  4. <view class="header">
  5. <image class="cover-img" :src="liveInfo.url" mode="widthFix"></image>
  6. <view class="flex" style="padding: 40rpx 40rpx 0 40rpx;">
  7. <view class="flex flex-column">
  8. <view class="title">{{ liveInfo.title }}</view>
  9. <view class="tag">{{ liveInfo.createTime }}</view>
  10. </view>
  11. <view v-if="isManager" class="flex operate">
  12. <view class="btn btn-add" @click="onAdd">新增记录</view>
  13. </view>
  14. </view>
  15. </view>
  16. <view class="main">
  17. <view class="section" v-for="item in list" :key="item.id">
  18. <view class="flex section-header">
  19. <view class="avatar">
  20. <image class="avatar-img" :src="item.avatar" mode="scaleToFill"></image>
  21. </view>
  22. <view class="info">
  23. <view class="flex title">
  24. <view>{{ item.createBy }}</view>
  25. <image class="icon" src="@/static/image/icon-location.png" mode="widthFix"></image>
  26. <view class="address text-ellipsis">{{ item.address }}</view>
  27. </view>
  28. <view class="desc">{{ item.createTime }}</view>
  29. </view>
  30. </view>
  31. <view class="section-content record">
  32. <view class="record-item" v-for="(image, imgIdx) in item.images" :key="imgIdx">
  33. <image class="img" :src="image" mode="aspectFill"></image>
  34. </view>
  35. </view>
  36. </view>
  37. </view>
  38. <formPopup ref="formPopup" @submitted="getData"></formPopup>
  39. </view>
  40. </template>
  41. <script>
  42. import { mapState } from 'vuex'
  43. import mixinsList from '@/mixins/list.js'
  44. import SYStackedCarousel from '@/uni_modules/SY-StackedCarousel/components/SY-StackedCarousel/SY-StackedCarousel.vue'
  45. import formPopup from './formPopup.vue'
  46. export default {
  47. mixins: [mixinsList],
  48. components: {
  49. SYStackedCarousel,
  50. formPopup,
  51. },
  52. data() {
  53. return {
  54. current: 0,
  55. queryParams: {
  56. pageNo: 1,
  57. pageSize: 10,
  58. imageId: '',
  59. },
  60. mixinsListApi: 'queryImageContentList',
  61. // todo: fetch
  62. isManager: true,
  63. }
  64. },
  65. computed: {
  66. ...mapState(['liveInfo']),
  67. },
  68. onLoad(arg) {
  69. const { id } = arg
  70. this.queryParams.imageId = id
  71. this.getData()
  72. },
  73. methods: {
  74. getCoverImage(image) {
  75. return image?.split?.(',')?.[0]
  76. },
  77. getDataThen(records) {
  78. this.list = records.map(item => {
  79. const { id, avatar, createBy, address, image, createTime } = item
  80. return {
  81. id,
  82. // todo: check key
  83. avatar: avatar || '/pages_order/static/center/avatar-default.png',
  84. createBy,
  85. address,
  86. images: image?.split?.(',') || [],
  87. createTime,
  88. }
  89. })
  90. },
  91. onAdd() {
  92. this.$refs.formPopup.open()
  93. },
  94. },
  95. }
  96. </script>
  97. <style lang="scss" scoped>
  98. .header {
  99. margin-top: 40rpx;
  100. font-size: 0;
  101. .cover-img {
  102. width: 100%;
  103. height: auto;
  104. border-radius: 40rpx;
  105. }
  106. .title {
  107. font-size: 28rpx;
  108. font-weight: 600;
  109. color: #252545;
  110. }
  111. .tag {
  112. margin-top: 4rpx;
  113. padding: 2rpx 8rpx;
  114. font-size: 24rpx;
  115. color: #00A9FF;
  116. background: #E0F5FF;
  117. border-radius: 8rpx;
  118. }
  119. .operate {
  120. flex: 1;
  121. justify-content: flex-end;
  122. .btn-add {
  123. padding: 6rpx 22rpx;
  124. font-family: PingFang SC;
  125. font-size: 28rpx;
  126. font-weight: 500;
  127. line-height: 1.5;
  128. color: #FFFFFF;
  129. background: linear-gradient(to right, #21FEEC, #019AF9);
  130. border: 2rpx solid #00A9FF;
  131. border-radius: 30rpx;
  132. }
  133. }
  134. }
  135. .main {
  136. padding: 0 40rpx 40rpx 40rpx;
  137. }
  138. .section {
  139. margin-top: 40rpx;
  140. &-header {
  141. column-gap: 24rpx;
  142. .avatar {
  143. flex: none;
  144. width: 100rpx;
  145. height: 100rpx;
  146. border: 4rpx solid #FFFFFF;
  147. border-radius: 50%;
  148. overflow: hidden;
  149. &-img {
  150. width: 100%;
  151. height: 100%;
  152. }
  153. }
  154. .info {
  155. flex: 1;
  156. min-width: 0;
  157. .title {
  158. column-gap: 8rpx;
  159. white-space: nowrap;
  160. font-size: 36rpx;
  161. font-weight: 600;
  162. color: #252545;
  163. .icon {
  164. width: 32rpx;
  165. height: 32rpx;
  166. }
  167. .address {
  168. flex: 1;
  169. font-weight: 400;
  170. font-size: 24rpx;
  171. color: #00A9FF;
  172. }
  173. }
  174. .desc {
  175. margin-top: 8rpx;
  176. font-size: 24rpx;
  177. font-weight: 400;
  178. color: #8B8B8B;
  179. }
  180. }
  181. }
  182. &-content {
  183. margin-top: 24rpx;
  184. }
  185. }
  186. .record {
  187. display: grid;
  188. grid-template-columns: repeat(3, 1fr);
  189. gap: 16rpx;
  190. &-item {
  191. height: 300rpx;
  192. border: 2rpx solid #CDCDCD;
  193. border-radius: 12rpx;
  194. overflow: hidden;
  195. .img {
  196. width: 100%;
  197. height: 100%;
  198. }
  199. }
  200. }
  201. </style>