木邻有你前端代码仓库
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.

424 lines
9.0 KiB

1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
  1. <template>
  2. <view class="community-page">
  3. <!-- 顶部图片 -->
  4. <view class="banner-section">
  5. <!-- <image class="banner-image" :src="currentTab === 'current' ? '/static/社区_背景.png' : '/static/社区_背景2.png'" mode="aspectFit"></image> -->
  6. <uv-swiper :list="bannerList" indicator indicatorMode="line" height="375rpx" ></uv-swiper>
  7. </view>
  8. <!-- Tab切换区域 -->
  9. <view class="tab-section">
  10. <view class="tab-container">
  11. <view
  12. class="tab-item"
  13. :class="{ active: currentTab === 'current' }"
  14. @click="switchTab('current')"
  15. >
  16. <text class="tab-text">木邻说</text>
  17. <view class="tab-line" v-if="currentTab === 'current'"></view>
  18. </view>
  19. <view
  20. class="tab-item"
  21. :class="{ active: currentTab === 'past' }"
  22. @click="switchTab('past')"
  23. >
  24. <text class="tab-text">木邻见</text>
  25. <view class="tab-line" v-if="currentTab === 'past'"></view>
  26. </view>
  27. </view>
  28. </view>
  29. <!-- 动态列表 -->
  30. <view class="post-list">
  31. <view
  32. class="post-item"
  33. v-for="(item, index) in list"
  34. :key="index"
  35. >
  36. <!-- 用户信息 -->
  37. <view class="user-info">
  38. <image class="user-avatar" :src="item.member.headImage" mode="aspectFill"></image>
  39. <view class="user-details">
  40. <text class="username">{{ item.member.nickName }}</text>
  41. <text class="post-time">发布时间{{ item.createTime }}</text>
  42. </view>
  43. </view>
  44. <!-- 动态内容 -->
  45. <view class="post-content">
  46. <text class="post-text">{{ item.content }}</text>
  47. <!-- 图片列表 -->
  48. <view class="image-grid" v-if="item.image && item.image.length > 0">
  49. <image
  50. class="post-image"
  51. v-for="(img, imgIndex) in item.image.split(',')"
  52. :key="imgIndex"
  53. :src="img"
  54. mode="aspectFill"
  55. ></image>
  56. </view>
  57. </view>
  58. <!-- 回复列表 -->
  59. <view class="comment-list" v-if="item.communityCommentList && item.communityCommentList.length > 0">
  60. <view class="comment-header">
  61. <text class="comment-title">回复 ({{ item.communityCommentList.length }})</text>
  62. </view>
  63. <view
  64. class="comment-item"
  65. v-for="(comment, commentIndex) in item.communityCommentList"
  66. :key="commentIndex"
  67. >
  68. <view class="comment-user-info">
  69. <text class="comment-username">{{ comment.createBy }}</text>
  70. <text class="comment-time">{{ comment.createTime }}</text>
  71. </view>
  72. <text class="comment-content">{{ comment.content }}</text>
  73. <img :src="comment.image" class="comment-image" mode="aspectFill" alt="" v-if="comment.image">
  74. </view>
  75. </view>
  76. </view>
  77. </view>
  78. <!-- 随手拍/我要留言按钮 -->
  79. <view class="action-btn" :class="currentTab === 'current' ? 'current-btn' : 'photo'" @click="openAction">
  80. <uv-icon name="edit-pen-fill" size="20" color="white"></uv-icon>
  81. <text class="action-text">{{ actionButtonText }}</text>
  82. </view>
  83. </view>
  84. </template>
  85. <script>
  86. import ListMixin from '@/mixins/list.js'
  87. export default {
  88. mixins: [ListMixin],
  89. name: 'CommunityPage',
  90. data() {
  91. return {
  92. currentTab: 'current', // current: 木邻说, past: 木邻见
  93. mixinListApi: 'community.queryPostList',
  94. bannerList: []
  95. }
  96. },
  97. computed: {
  98. actionButtonText() {
  99. return this.currentTab === 'current' ? '我要留言' : '随手拍'
  100. }
  101. },
  102. methods: {
  103. mixinSetParams(){
  104. if (uni.getStorageSync('token')){
  105. return {
  106. token: uni.getStorageSync('token'),
  107. type: this.currentTab === 'current' ? 0 : 1
  108. }
  109. }
  110. return {
  111. type: this.currentTab === 'current' ? 0 : 1
  112. }
  113. },
  114. switchTab(tab) {
  115. this.currentTab = tab
  116. this.initPage()
  117. this.getList(true)
  118. this.getBannerList()
  119. },
  120. openAction() {
  121. if (this.currentTab === 'current') {
  122. // 我要留言功能
  123. this.goToComment()
  124. } else {
  125. this.takePhoto()
  126. }
  127. },
  128. takePhoto() {
  129. uni.navigateTo({
  130. url: '/subPages/community/publishPost?page=photo'
  131. })
  132. },
  133. goToComment() {
  134. uni.navigateTo({
  135. url: '/subPages/community/publishPost'
  136. })
  137. },
  138. // 获取帖子数据
  139. async getPostList() {
  140. const res = await this.$api.community.queryPostList({
  141. pageNo: this.pageNo,
  142. pageSize: this.pageSize,
  143. type: this.currentTab === 'current' ? 0 : 1
  144. })
  145. if (res.result.records.length) {
  146. this.postList.push(...res.result.records)
  147. this.pageNo++
  148. }else {
  149. uni.showToast({
  150. title: '暂无数据',
  151. icon: 'none'
  152. })
  153. }
  154. },
  155. // 获取顶部轮播图
  156. async getBannerList() {
  157. const res = await this.$api.home.queryBannerList({
  158. type: this.currentTab === 'current' ? 1 : 2
  159. })
  160. // console.log('返回的结果', res);
  161. if (res.result.records.length) {
  162. this.bannerList = res.result.records.map(item => item.image)
  163. }
  164. }
  165. },
  166. onShow() {
  167. this.getBannerList()
  168. }
  169. }
  170. </script>
  171. <style lang="scss" scoped>
  172. .community-page {
  173. min-height: 100vh;
  174. background-color: #f8f9fa;
  175. position: relative;
  176. padding-bottom: 120rpx;
  177. }
  178. // 横幅样式
  179. .banner-section {
  180. height: 375rpx;
  181. overflow: hidden;
  182. }
  183. // .banner-image {
  184. // width: 100%;
  185. // height: 100%;
  186. // }
  187. // Tab切换区域
  188. .tab-section {
  189. background: white;
  190. padding: 0 40rpx;
  191. border-bottom: 1rpx solid #f0f0f0;
  192. box-shadow: 0px 1.5px 3px 0px rgba(0,0,0,0.16);
  193. }
  194. .tab-container {
  195. display: flex;
  196. // gap: 60rpx;
  197. justify-content: space-evenly;
  198. }
  199. .tab-item {
  200. position: relative;
  201. padding: 30rpx 0;
  202. .tab-text {
  203. font-size: 32rpx;
  204. color: #666;
  205. font-weight: 500;
  206. transition: color 0.3s ease;
  207. }
  208. &.active {
  209. .tab-text {
  210. color: #007AFF;
  211. font-weight: bold;
  212. }
  213. }
  214. }
  215. .tab-line {
  216. position: absolute;
  217. bottom: 0;
  218. left: 50%;
  219. transform: translateX(-50%);
  220. width: 40rpx;
  221. height: 6rpx;
  222. background: #007AFF;
  223. border-radius: 3rpx;
  224. animation: slideIn 0.3s ease;
  225. }
  226. @keyframes slideIn {
  227. from {
  228. width: 0;
  229. }
  230. to {
  231. width: 40rpx;
  232. }
  233. }
  234. // 动态列表样式
  235. .post-list {
  236. // padding: 20rpx;
  237. }
  238. .post-item {
  239. background-color: white;
  240. border-radius: 16rpx;
  241. // margin-bottom: 24rpx;
  242. padding: 32rpx;
  243. box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.06);
  244. border: 1rpx solid #f5f5f5;
  245. transition: transform 0.2s ease, box-shadow 0.2s ease;
  246. &:active {
  247. transform: scale(0.98);
  248. box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
  249. }
  250. }
  251. .user-info {
  252. display: flex;
  253. align-items: center;
  254. margin-bottom: 24rpx;
  255. }
  256. .user-avatar {
  257. width: 88rpx;
  258. height: 88rpx;
  259. border-radius: 50%;
  260. margin-right: 24rpx;
  261. border: 2rpx solid #f0f0f0;
  262. }
  263. .user-details {
  264. flex: 1;
  265. }
  266. .username {
  267. font-size: 30rpx;
  268. font-weight: bold;
  269. color: #333;
  270. display: block;
  271. margin-bottom: 8rpx;
  272. }
  273. .post-time {
  274. font-size: 24rpx;
  275. color: #999;
  276. }
  277. .post-content {
  278. .post-text {
  279. font-size: 30rpx;
  280. color: #333;
  281. line-height: 1.6;
  282. display: block;
  283. margin-bottom: 24rpx;
  284. }
  285. }
  286. .image-grid {
  287. display: flex;
  288. flex-wrap: wrap;
  289. gap: 12rpx;
  290. }
  291. .post-image {
  292. width: 227rpx;
  293. height: 303rpx;
  294. border-radius: 12rpx;
  295. border: 1rpx solid #f0f0f0;
  296. }
  297. // 回复列表样式
  298. .comment-list {
  299. margin-top: 24rpx;
  300. padding-top: 24rpx;
  301. border-top: 1rpx solid #f3f7f8;
  302. }
  303. .comment-header {
  304. margin-bottom: 20rpx;
  305. }
  306. .comment-title {
  307. font-size: 28rpx;
  308. color: #666;
  309. font-weight: 500;
  310. }
  311. .comment-item {
  312. background-color: #f8f9fa;
  313. border-radius: 12rpx;
  314. padding: 20rpx;
  315. margin-bottom: 16rpx;
  316. &:last-child {
  317. margin-bottom: 0;
  318. }
  319. }
  320. .comment-user-info {
  321. display: flex;
  322. align-items: center;
  323. justify-content: space-between;
  324. margin-bottom: 12rpx;
  325. }
  326. .comment-username {
  327. font-size: 26rpx;
  328. color: #007AFF;
  329. font-weight: 500;
  330. }
  331. .comment-time {
  332. font-size: 22rpx;
  333. color: #999;
  334. }
  335. .comment-content {
  336. font-size: 28rpx;
  337. color: #333;
  338. line-height: 1.5;
  339. display: block;
  340. }
  341. .comment-image {
  342. width: 95px;
  343. height: 95px;
  344. background: rgba(0,0,0,0.00);
  345. border-radius: 4.5px;
  346. }
  347. // 随手拍/我要留言按钮样式
  348. .action-btn {
  349. position: fixed;
  350. bottom: 120rpx;
  351. right: 30rpx;
  352. width: 120rpx;
  353. height: 120rpx;
  354. background: linear-gradient(135deg, #007AFF 0%, #0056CC 100%);
  355. border-radius: 50%;
  356. display: flex;
  357. flex-direction: column;
  358. align-items: center;
  359. justify-content: center;
  360. box-shadow: 0 8rpx 24rpx rgba(0, 122, 255, 0.4);
  361. z-index: 100;
  362. transition: transform 0.2s ease, box-shadow 0.2s ease;
  363. &:active {
  364. transform: scale(0.95);
  365. box-shadow: 0 4rpx 16rpx rgba(0, 122, 255, 0.6);
  366. }
  367. &.photo {
  368. background: linear-gradient(135deg, #FF6666 0%, #CC3333 100%);
  369. }
  370. }
  371. .action-text {
  372. font-size: 20rpx;
  373. color: white;
  374. margin-top: 8rpx;
  375. font-weight: bold;
  376. }
  377. </style>