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

416 lines
8.8 KiB

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